0

我对 xslt 比较陌生,但我有一些运气来设计一个巨大的 xml 文件。现在我被困在一个地方,无法继续。可以说xml文件的结构有点像

<xxx>
.......
.......
.......
 <Field id="123" type="fld" elem="3">
   <td:value passed="true"> 25 </td:value>
 </Field>
.......
.......
.......

</xxx>

我目前在 Field 节点。如果我这样做,<xsl:value of select="name()" />它会给出“Field”,如果我这样做,<xsl:value of select="@type" />我会得到“fld”。但如果我这样做,<xsl:value of select="." />我得到的值<td:value>是 25。

我担心的是我需要在 td:value 中获取“通过”属性的值。如果我从当前位置使用以下模板,我可以访问该属性。

<xsl:apply-templates select="*[@passed]" />

  <xsl:template match="*[@passed]" >
       <xsl:value-of select="@passed" />
     </xsl:template>

但问题是“通过”属性可能并不总是存在,所以我需要<td:value>只使用节点名称来访问节点。

我试过

<xsl:apply-templates select=".//td" />
<xsl:apply-templates select=".//td:value" />
<xsl:apply-templates select=".//*" />
<xsl:apply-templates select=".*" />
<xsl:apply-templates select="td" />

似乎没有任何效果。我如何从 Field 节点到达那个 td:value 节点?

4

2 回答 2

2

您需要在输入 XML中声明分配给td前缀 of的相同命名空间。td:value例如:

<foo xmlns:td="urn:td">
  <Fieldid="123" type="fld" elem="3">
    <td:value passed="true"> 25 </td:value>
  </Field>
</foo>

XSLT 可能类似于:

<xsl:template match="Field">
  <xsl:if test="td:value@passed" xmlns:td="urn:td">
    <xsl:value-of select="td:value"/>
  </xsl:if>
</xsl:template>

重要的部分是名称空间与输入文档中的名称相同,XSLT 文档中的前缀名称是否不同都没有关系。如果可能,并且如果所有 XML 都在您的控制之下,那么为了清楚起见,它应该是。

于 2012-11-01T17:04:22.870 回答
1

澄清一下,您当前位于field元素上,并且您正在尝试选择子td:value以获取其@passed属性,但如果此属性不存在,您希望获取获取元素的值反而。

嗯,你可以做的是首先做的是替换这个

<xsl:apply-templates select="*[@passed]" />

有了这个

<xsl:apply-templates select="*" />

然后,您需要两个匹配的模板;一种用于当属性存在时,一种用于捕获其他情况

<xsl:template match="Field/*[@passed]" >
   <xsl:value-of select="@passed" />
</xsl:template>

<xsl:template match="Field/*" >
   <xsl:value-of select="." />
</xsl:template>

当您有两个这样的模板时,XSLT 将首先匹配更具体的一个。因此,如果存在@passed属性,则始终匹配第一个模板(即使第二个模板也匹配它)。当没有一个存在时,将使用第二个。

编辑:如果你不想指定元素名称,你可以用这个替换你的模板......

<xsl:template match="*[@passed]" >
   <xsl:value-of select="@passed" />
</xsl:template>

<xsl:template match="*" >
   <xsl:value-of select="." />
</xsl:template>

但是,这些将开始匹配可能影响 XSLT 其他部分的所有元素。因此,您可能必须在此处使用mode参数

<xsl:apply-templates select="*" mode="Field" />

<xsl:template match="*[@passed]" mode="Field" >
   <xsl:value-of select="@passed" />
</xsl:template>

<xsl:template match="*" mode="Field" >
   <xsl:value-of select="." />
</xsl:template>
于 2012-11-01T17:00:08.610 回答