在XPath 1.0中,如果一个函数或运算符期望一个字符串,并传递了一个节点集,则仅产生并使用节点集中第一个(按文档顺序)节点的字符串值。
因此,像这样的表达式:
contains(name, msxsl:node-set($Var)/root/tag/@atr)
测试仅检查msxsl:node-set($Var)/root/tag/@atr
节点中的第一个节点的字符串值是否包含在第一个name
节点的字符串值中。
实际上,您想要查看msxsl:node-set($Var)/root/tag/@atr
中任何节点的字符串值是否包含在名为name
的给定元素的字符串值中。
满足此条件的一个正确的XPath表达式为:
boolean(msxsl:node-set($Var)/root/tag/@atr[contains($name, .)])
$name
定义为包含元素name
的完整代码示例:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="name" select="'x42'"/>
<xsl:variable name="Var">
<root>
<tag atr="x3"> some string </tag>
<tag atr="x4"> some string </tag>
</root>
</xsl:variable>
<xsl:template match="/">
<xsl:value-of select=
"boolean(msxsl:node-set($Var)
/root/tag/@atr[contains($name, .)])"/>
</xsl:template>
</xsl:stylesheet>
当将此转换应用于任何XML文档(未使用),则会产生所需的正确结果:
true
然而,如果我们在上述转换中替换为另一个答案(Siva Charan提供的XPath表达式)中提供的XPath表达式:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="name" select="'x42'"/>
<xsl:variable name="Var">
<root>
<tag atr="x3"> some string </tag>
<tag atr="x4"> some string </tag>
</root>
</xsl:variable>
<xsl:template match="/">
<xsl:value-of select=
"contains(name, msxsl:node-set($Var)/root/tag/@atr)"/>
</xsl:template>
</xsl:stylesheet>
这个转换产生了错误的答案:
false
因为它只测试所有attr
属性中的第一个是否包含。
contains()
接受字符串参数,因此您不能将节点集传递给它。您需要逐个检查节点集中的每个项目。 - Francis Avila