XSLT: могу ли я объявить переменную глобально, а затем присвоить ей значение - PullRequest
23 голосов
/ 17 ноября 2010

Что я могу сделать, чтобы этот код работал?

<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' />, я уже установил эту переменную раньше.Как мне решить это?

Ответы [ 5 ]

31 голосов
/ 17 ноября 2010

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

<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>
13 голосов
/ 17 ноября 2010
<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> 

Это не работает

Это FAQ :

Вы определяете несколько переменных, каждая из которых называется $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'
 "/>
4 голосов
/ 17 ноября 2010

Вы не можете переназначить переменные в XSLT (1.0). Название, вероятно, не выбрано удачно; 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>
2 голосов
/ 17 ноября 2010

Помимо стандартного ответа @ carolclarinet и более компактного ответа @ Dimitre, когда результат зависит от какого-либо узла и вас беспокоит повторное использование и расширяемость, вы можете применять шаблоны и использовать сопоставление с образцом, например:

<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>
0 голосов
/ 10 февраля 2017

Я делаю это, чтобы сохранить локальное значение в xml xsl:desult _документ в папку /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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...