Копирование переменной XSLT - PullRequest
7 голосов
/ 01 октября 2010

Я работаю над таблицей стилей Umbraco XSL, и я довольно застрял.

По сути, у меня есть параметр, который я тестирую и использую его значение, если оно присутствует, в противном случае я использую параметр по умолчанию $currentPage.

Вот параметры

<xsl:param name="source" select="/macro/sourceId" />
<xsl:param name="currentPage" />

Вот переменная

<xsl:variable name="current">
    <xsl:choose>
        <xsl:when test="$source &gt; 0">
            <xsl:copy-of select="umbraco.library:GetXmlNodeById($source)" />
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy-of select="$currentPage" />
        </xsl:otherwise>
    </xsl:choose>
</xsl:variable>

А вот где я его использую

<xsl:for-each select="msxml:node-set($source)/ancestor-or-self::* [@isDoc and @level=$level]/* [@isDoc and string(umbracoNaviHide) != '1']">
... code here ...
</xsl:for-each>


В двух словах

Это работает

<xsl:variable name="source" select="$currentPage" />

Это не

<xsl:variable name="source">
  <xsl:copy-of select="$currentPage" /> <!-- Have tried using <xsl:value-of /> as well -->
</xsl:variable>

Как скопировать переменную без использования атрибута select="".

ОБНОВЛЕНИЕ: Я пытался использовать другой подход (см. Ниже), но я получаю переменную вне области действия исключение.

<xsl:choose>
    <xsl:when test="$source &gt; 0">
        <xsl:variable name="current" select="umbraco.library:GetXmlNodeById($source)" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:variable name="current" select="$currentPage" />
    </xsl:otherwise>
</xsl:choose>

Ответы [ 2 ]

6 голосов
/ 01 октября 2010

Обычно это выражение выбирает один из двух наборов узлов в зависимости от того, является ли данное условие true() или false():

$ns1[$cond] | $ns2[not($cond)]

В вашем случае это означает :

    umbraco.library:GetXmlNodeById($source) 
|
    $currentPage[not(umbraco.library:GetXmlNodeById($source))]

Полное <xsl:variable> определение :

<xsl:variable name="vCurrent" select=
"        umbraco.library:GetXmlNodeById($source) 
    |
        $currentPage[not(umbraco.library:GetXmlNodeById($source))]
"/>

Это можно записать более компактным способом :

<xsl:variable name="vRealSource" select="umbraco.library:GetXmlNodeById($source)"/>

<xsl:variable name="vCurrent" select=
    "$vRealSource| $currentPage[not($vRealSource)]"/>
2 голосов
/ 01 октября 2010

Всякий раз, когда вы объявляете переменную в XSLT 1.0 без @select, но с некоторым шаблоном содержимого, тип переменной будет Result Tree Fragment.Переменная содержит корневой узел этого фрагмента дерева.

Итак, с этим:

<xsl:variable name="source"> 
  <xsl:copy-of select="$currentPage" />
</xsl:variable> 

Вы объявляете $source как корень RTF, содержащий copy узлов (себя и потомков) в наборе $currentPage узлов.

Нельзя использовать шаговый оператор / с RTF.Вот почему вы используете node-set функцию расширения.

Но , когда вы говорите:

node-set($source)/ancestor-or-self::*

Это будет оцениваться как пустой набор узлов, потому чтоКорневой узел не имеет предков и не является элементом.

РЕДАКТИРОВАТЬ : Если у вас есть два набора узлов, и вы хотите объявить переменную с содержимым одного из двух наборов узлов в зависимости от некоторых условий, вы можете использовать:

<xsl:variable name="current" 
              select="umbraco.library:GetXmlNodeById($source)[$source > 0]
                      |$currentPage[0 >= $source]" /> 
...