В 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
Однако, если мы заменим в приведенном выше преобразовании выражение 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
.