Xml 如何在xslt中找到从节点到其子节点的相对xpath表示法?
我对xslt比较陌生,但我有幸设计了一个巨大的xml文件的样式。现在我被困在一个地方,无法继续前进。假设xml文件的结构有点像Xml 如何在xslt中找到从节点到其子节点的相对xpath表示法?,xml,xslt,xpath,Xml,Xslt,Xpath,我对xslt比较陌生,但我有幸设计了一个巨大的xml文件的样式。现在我被困在一个地方,无法继续前进。假设xml文件的结构有点像 <xxx> ....... ....... ....... <Field id="123" type="fld" elem="3"> <td:value passed="true"> 25 </td:value> </Field> ....... ....... ....... </xxx&g
<xxx>
.......
.......
.......
<Field id="123" type="fld" elem="3">
<td:value passed="true"> 25 </td:value>
</Field>
.......
.......
.......
</xxx>
.......
.......
.......
25
.......
.......
.......
我当前在字段节点中。如果我做一个
它会给出“Field”,如果我做一个
我会得到“fld”。但是如果我做一个
,我会得到
中的值,即25
我关心的是,我需要在td:value中获取'passed'属性的值。如果从当前位置使用以下模板,则可以访问该属性
<xsl:apply-templates select="*[@passed]" />
<xsl:template match="*[@passed]" >
<xsl:value-of select="@passed" />
</xsl:template>
但问题是“passed”属性可能并不总是存在,因此我需要只使用节点名称访问
节点
我试过了
<xsl:apply-templates select=".//td" />
<xsl:apply-templates select=".//td:value" />
<xsl:apply-templates select=".//*" />
<xsl:apply-templates select=".*" />
<xsl:apply-templates select="td" />
似乎什么都不管用。如何从字段节点到达td:value节点 只是澄清一下,您当前位于字段元素上,并且您正试图选择子td:value以获取其@传递的属性,但是如果该属性不存在,则您希望获取元素的值 好吧,你能做的就是先换掉这个
<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其他部分的所有元素。因此,您可能必须在这里使用模式参数
<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>
只是澄清一下,您当前位于字段元素上,您正试图选择子td:value以获取其@传递的属性,但如果该属性不存在,则您希望获取元素的值 好吧,你能做的就是先换掉这个
<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其他部分的所有元素。因此,您可能必须在这里使用模式参数
<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>
您需要声明在输入XML中分配给
td:value
的td
前缀的名称空间。例如:
<foo xmlns:td="urn:td">
<Fieldid="123" type="fld" elem="3">
<td:value passed="true"> 25 </td:value>
</Field>
</foo>
25
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都在您的控制之下,为了清楚起见,应该是这样。您需要声明在输入XML中分配给
td:value
前缀td
的名称空间。例如:
<foo xmlns:td="urn:td">
<Fieldid="123" type="fld" elem="3">
<td:value passed="true"> 25 </td:value>
</Field>
</foo>
25
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都在您的控制之下,为了清楚起见,它应该在您的XSLT知道
td:
名称空间吗?是的,存在xmlns:td=“somewebsite”名称空间声明。您的XSLT知道td:
名称空间吗?是的,存在xmlns:td=“somewebsite”名称空间声明。嘿,蒂姆,谢谢你的快速回答。我忘了再提一个。标记“字段”不一致,在每种情况下可能不同。那么现在如何引用模板而不是“Field/*[@passed]”和“Field/*”?啊,我完全忘记了mode参数。现在很好用。非常感谢你的帮助,伙计!嘿,蒂姆,谢谢你的快速回答。我忘了再提一个。标记“字段”不一致,在每种情况下可能不同。那么现在如何引用模板而不是“Field/*[@passed]”和“Field/*”?啊,我完全忘记了mode参数。现在很好用。非常感谢你的帮助,伙计!Paulo,
会不会在模板中没有提到xmlns:td?是否强制执行?要特别匹配td:value
,是的。您可以在任何包含节点中声明名称空间,如rootxsl:stylesheet
。但是,如果您真的想忽略名称空间,请尝试
。Paulo,
在模板中不提及xmlns:td,它会工作吗?是否强制执行?要特别匹配td:value
,是的。您可以在任何包含节点中声明名称空间,如rootxsl:stylesheet
。但是,如果确实要忽略名称空间,请尝试
。