Как использовать переменную node-set в Xpath, функция «contains ()» - PullRequest
2 голосов
/ 06 марта 2012

Я хочу проверить, содержит ли значение узла строку, встречающуюся в атрибуте узла с переменной in-in, сделанной как набор узлов.

<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 Ответ

3 голосов
/ 07 марта 2012

В 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.

...