In XPath 1.0 if a function or operator expects a string and is passed a node-set, only the string value of the first (in document order) node of the node-set is produced and used by this function or operator.
Therefore, an expression such as:
contains(name, msxsl:node-set($Var)/root/tag/@atr)
tests only whether the string value of the first of the msxsl:node-set($Var)/root/tag/@atr nodes is contained in the string value of the first name node.
You actually want to see if the string value of any of the nodes in msxsl:node-set($Var)/root/tag/@atr is contained in a the string value of a given element, named name.
One correct XPath expression evaluating this condition:
boolean(msxsl:node-set($Var)/root/tag/@atr[contains($name, .)])
where $name is defined to contain exactly the element name.
A complete code example:
<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>
when this transformation is applied on any XML document (not used), the wanted, correct result is produced:
true
However, if we substitute in the above transformation the XPath expression offered in the another answer (by 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>
this transformation produces the wrong answer:
false
because it only tests for containment the first of all attr attributes.
contains()accepts string arguments, so you can't pass it a nodeset. You need to check against every item in the nodeset individually. - Francis Avila