如何在Xpath“contains()”函数中使用变量node-set

时间:2012-03-06 17:55:35

标签: xml xpath xslt-1.0

我想检查节点值是否包含一个字符串,该字符串出现在作为节点集的节点变量节点的属性中。

<xsl:variable name="Var">
<root>
   <tag atr="x3"> some string <tag> 
   <tag atr="x4"> some string <tag>
<root>
<xsl:variable>

xml包含:

<name>one x3 two<name> 

我尝试过类似的事情:

<xsl:value-of select="contains(name,msxsl:node-set($Var)/root/tag/@atr)"/>

但它只输出什么并继续前进。

1 个答案:

答案 0 :(得分:3)

在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的给定元素的字符串值中。< / p>

评估此条件的一个正确的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

但是,如果我们在上面的转换中替换另一个答案中提供的XPath表达式(由Siva Charan提供):

<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属性的第一个。