2010-11-17 1 views
18

Что я могу сделать, чтобы этот код работал?XSLT: могу ли я объявить переменную глобально и позже присвоить ей значение

<xsl:choose> 
    <xsl:when test='type = 6'> 
    <xsl:variable name='title' select='root/info/title' /> 
    </xsl:when> 
    <xsl:when test='type = 7'> 
    <xsl:variable name='title' select='root/name' /> 
    </xsl:when> 
    <xsl:otherwise> 
    <xsl:variable name='title'>unknown</xsl:variable> 
    </xsl:otherwise> 
</xsl:choose> 

<div class='title'> 
    <xsl:value-of select='$title'/> 
</div> 

Это не работает, потому что, когда я делаю <xsl:value-of select='$title'/>, $title выходит за рамки. Я попытался добавить строку <xsl:variable name='title'/> за пределы области действия, но это тоже не сработает, потому что тогда, когда я вызываю <xsl:variable name='title' select='root/info/title' />, например, я уже задал эту переменную раньше. Как мне это решить?

+1

Хороший вопрос, +1. См. Мой ответ для трех разных решений. :) –

ответ

27

Вы можете переместить выбрать внутри установки переменной, например:

<xsl:variable name="title"> 
    <xsl:choose> 
    <xsl:when test='type=6'> 
     <xsl:value-of select="root/info/title" /> 
    </xsl:when> 
    ... 
    </xsl:choose> 
</xsl:variable> 

<div class='title'> 
    <xsl:value-of select="$title" /> 
</div> 
+1

Да, это то, о чем я тоже думал. Мне не очень нравится это решение, потому что у меня более 20 типов, каждый из которых нуждается в 5 переменных. Если бы я мог перечислить эти 5 переменных для каждого типа один за другим, это сделало бы мой код более понятным, и было бы проще добавить другой тип. С предлагаемым решением, если нужно добавить строку для нового типа в каждой из пяти переменных. Но я думаю, что другого выхода не будет. Я получу это, спасибо за ответ :) –

+0

Вы можете сделать шаблон вызова внутри каждой переменной, а не выбирать, а затем выбрать в одном шаблоне. – carols10cents

+0

О, но подождите - тогда вам нужно будет проверить, какая переменная вы устанавливаете внутри шаблона;) – carols10cents

3

Вы не можете повторно назначать переменные в XSLT (1.0). Название, вероятно, не случайно выбрано; a xsl:variable - скорее символ, чем переменная.

В вашей выборке вы можете использовать следующее:

<xsl:variable name='title'> 
    <xsl:choose> 
    <xsl:when test='type = 6'> 
     <xsl:value-of select='root/info/title' /> 
    </xsl:when> 
    <xsl:when test='type = 7'> 
     <xsl:value-of select='root/name' /> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:text>unknown</xsl:text> 
    </xsl:otherwise> 
    </xsl:choose> 
</xsl:variable> 
+0

Это переменная, а не постоянный литерал. Но это переменная в декларативной парадигме: больше как переменная в уравнении. – 2010-11-17 14:30:41

+1

@Alejandro: Да, я имел в виду символ/переменную, как в математическом смысле, как описано Майклом Кей: «Некоторые люди спрашивали: зачем называть это переменной, если вы не можете ее изменить? Ответ лежит на традиционной математической использование переменной слова: переменная является символом, который может использоваться для обозначения разных значений в разных случаях ». (http://gandhimukul.tripod.com/xslt/facts.html) –

11
<xsl:choose> 
    <xsl:when test='type = 6'> 
    <xsl:variable name='title' select='root/info/title' /> 
    </xsl:when> 
    <xsl:when test='type = 7'> 
    <xsl:variable name='title' select='root/name' /> 
    </xsl:when> 
    <xsl:otherwise> 
    <xsl:variable name='title'>unknown</xsl:variable> 
    </xsl:otherwise> 
</xsl:choose> 

<div class='title'> 
    <xsl:value-of select='$title'/> 
</div> 

Это Безразлично» т

Это часто задаваемые вопросы:

Вы определяете несколько переменных, каждый из которых называется $title, и каждый бесполезен, так как он выходит из сферы действия немедленно.

Надлежащим образом в XSLT 1.0, чтобы определить переменную, основанную на условиях:

<xsl:variable name="vTitle"> 
    <xsl:choose> 
     <xsl:when test='type = 6'> 
     <xsl:value-of select='root/info/title' /> 
     </xsl:when> 
     <xsl:when test='type = 7'> 
     <xsl:value-of select='root/name' /> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:value-of select="'unknown'"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:variable> 

Другой способ определения той же переменной: В данном конкретном случае вы хотите, чтобы переменная иметь строку стоимость. Это может быть выражено в более компактной форме:

<xsl:variable name="vTitle2" select= 
"concat(root/info/title[current()/type=6], 
     root/name[current()/type=7], 
     substring('unknown', 1 div (type > 7 or not(type > 5))) 
     ) 
"/> 

Наконец, в XSLT 2.0 можно определить такую ​​переменную еще удобнее:

<xsl:variable name="vTitle3" as="xs:string" select= 
"if(type eq 6) 
    then root/info/title 
    else if(type eq 7) 
      then root/name 
      else 'unknown' 
"/> 
+0

'потому что он немедленно выходит из сферы видимости.« Я подозревал, что это так. Какой тег определяет область действия, 'xsl: choose'? Моя проблема в том, что я пытаюсь установить около 50 переменных в зависимости от одного теста, и я не хочу, чтобы каждая переменная повторяла тест. Я попытался сделать это логически похожим на (select, (when (a), variable *), (когда (b), variable *)), и поэтому я вышел из сферы действия ... есть ли способ использовать один тест для нескольких переменных, но все же сохранить их в области? – n611x007

1

Кроме @ carolclarinet-х STANDAR ответа и более компактный @ Ответ Димитрия, когда результат зависит от некоторого узла, и вы беспокоитесь о повторном использовании и расширяемости, вы можете применять шаблоны и использовать сопоставление шаблонов, то есть:

<xsl:variable name="title"> 
    <xsl:apply-templates select="type" mode="title"/> 
</xsl:variable> 

<xsl:template match="type[.=6]" mode="title"> 
    <xsl:value-of select='../root/info/title"/> 
</xsl:template> 
<xsl:template match="type[.=7]" mode="title"> 
    <xsl:value-of select='../root/name"/> 
</xsl:template> 
<xsl:template match="type" mode="title"> 
    <xsl:text>unknown</xsl:text> 
</xsl:template> 
-1

Я делаю это, чтобы сохранить локальное значение в xml xsl:desult _document в папку /temp_variables_loop/loop-data-id_(position()).xml.

И в следующем цикле я читал файлы с/temp_variables_loop.alias/loop-data-id_(position()-1).xml.

Вам необходимо обмануть двигатель xsl, сделав псевдоним /temp_variables_loop, temp_variables_loop.alias, потому что вы не можете читать и писать в один файл в одном xsl.

Смежные вопросы