‹xsl:variable› Распечатать значение переменной XSL, используя ‹xsl:value-of›

Я пытаюсь вывести буквальное строковое значение переменной после его установки в зависимости от того, существует узел или нет. Я думаю, что логика проверки условия верна. Но он не выводит значения...

<xsl:variable name="subexists"/>

<xsl:template match="class">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
<xsl:choose>
    <xsl:when test="joined-subclass">
        <xsl:variable name="subexists" select="'true'"/>
    </xsl:when>
    <xsl:otherwise>
        <xsl:variable name="subexists" select="'false'"/>
    </xsl:otherwise>
</xsl:choose>
subexists:  <xsl:value-of select="$subexists" />

I want it to output the literal string of either "true" of "false". But it is not outputing anything. Please help! Thank you!!!


person tomato    schedule 13.04.2009    source источник


Ответы (3)


В этом случае для установки переменной не требуется никаких условий.

Это однострочное выражение XPath:

boolean(joined-subclass)

равно true() только тогда, когда существует дочерний элемент текущего узла с именем joined-subclass, и false() в противном случае.

Полная таблица стилей:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes"/>

 <xsl:template match="class">
   <xsl:variable name="subexists"
        select="boolean(joined-subclass)"
   />

   subexists:  <xsl:text/>
   <xsl:value-of select="$subexists" />
 </xsl:template>
</xsl:stylesheet>

Обратите внимание, что использование функции XPath boolean() в этом выражении означает преобразование узла (или его отсутствия) в одно из логических значений true() или false().

person Dimitre Novatchev    schedule 13.04.2009

Ваша основная проблема заключается в том, что вы думаете, что переменная, которую вы объявили вне шаблона, является той же самой переменной, которая «устанавливается» внутри оператора выбора. Это не то, как работает XSLT, переменная не может быть переназначена. Это больше похоже на то, что вы хотите:

<xsl:template match="class">
  <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
  <xsl:variable name="subexists">
    <xsl:choose>
      <xsl:when test="joined-subclass">true</xsl:when>
      <xsl:otherwise>false</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  subexists:      <xsl:value-of select="$subexists" />
</xsl:template>

И если вам нужно, чтобы переменная имела «глобальную» область действия, объявите ее вне шаблона:

<xsl:variable name="subexists">
  <xsl:choose>
     <xsl:when test="/path/to/node/joined-subclass">true</xsl:when>
     <xsl:otherwise>false</xsl:otherwise>
  </xsl:choose>
</xsl:variable>

<xsl:template match="class">
   subexists:      <xsl:value-of select="$subexists" />
</xsl:template>
person eddiegroves    schedule 13.04.2009

В XSLT одна и та же <xsl:variable> может быть объявлена ​​только один раз и может быть присвоено значение только при его объявлении. Если одновременно объявлено более одной переменной, они на самом деле являются разными переменными и имеют разную область действия.

Следовательно, способ достижения требуемой условной установки переменной и получения ее значения следующий:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes"/>

    <xsl:template match="class">
    <xsl:variable name="subexists">
            <xsl:choose>
                <xsl:when test="joined-subclass">true</xsl:when>
                <xsl:otherwise>false</xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        subexists:  <xsl:text/>    
        <xsl:value-of select="$subexists" />
    </xsl:template>
</xsl:stylesheet>

Когда указанное выше преобразование применяется к следующему XML-документу:

<class>
 <joined-subclass/>
</class>

получен желаемый результат:

    subexists:  true
person Dimitre Novatchev    schedule 13.04.2009