В XSLT как проверить, существует ли переменная?

при использовании XSLT как вы проверяете, существует ли локально ограниченная переменная или это вообще возможно?

7 ответов


рассматривая таблицу стилей XSLT как XML DOM, элемент объявления переменной делает переменную видимой для всех следующих братьев и сестер и их потомков. Это позволяет процессорам XSLT статически анализировать любой XPath, содержащий ссылку на переменную, чтобы увидеть, существует ли переменная; если объявление переменной существует на оси предыдущего брата или предка, ссылка на переменную является законной, иначе это не так.

обратите внимание, что это полностью зависит от структуры XSLT, а не структура XML, который он обрабатывает. Процессор XSLT может и должен выдавать ошибку, если выражение XPath использует несуществующую переменную.

нет способа проверить это условие внутри XSLT, потому что это условие не является законным в XSLT. Sitauation вы описали в своем комментарии - "идея состоит в том, чтобы установить переменную флага, если что-то выводится, а затем отобразить другое сообщение, если ничего не было выведено.- на самом деле это должно привести к синтаксической ошибке. Например, если вы делаете что-то вроде этого:

<xsl:if test="some_condition">
   <!-- produce output here -->
   <xsl:variable name="flag">true</xsl:variable>
</xsl:if>
<!-- time passes -->
<xsl:if test="$flag='true'>
   <!-- wouldn't it be nice? -->
</xsl:if>

вы получите синтаксическую ошибку: второй xsl:if элемент не является ни следующим братом объявления переменной, ни одним из их потомков.

вот метод, который я использую справедливое количество - это производит переменный вывод на основе различных условий, которые вы не хотите перепроверять позже:

<xsl:variable name="output">
   <xsl:if test="$condition1='true'">
      <p>condition1 is true</p>
   </xsl:if>
   <xsl:if test="$condition2='true'">
      <p>condition2 is true</p>
   </xsl:if>
   <xsl:if test="$condition3='true'">
      <p>condition3 is true</p>
   </xsl:if>
</xsl:variable>
<!-- we've produced the output, now let's actually *output* the output -->
<xsl:copy-of select="$output"/>
<!-- time passes -->
<xsl:if test="normalize-space($output) != ''">
   <p>This only gets emitted if $output got set to some non-empty value.</p>
</xsl:if>

этот вопрос указывает на то, что вы не полностью поняли ключевой момент XSLT. :-)

это декларативно: ничто не может существовать, если вы его не объявите. Вы объявляете переменную, тогда она есть, вы нет, тогда ее нет.

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

XSLT имеет строгие правила области видимости, переменные существуют только в пределах их родительского элемента (и не все элементы могут содержат переменные для начала). Как только вы оставите родительский элемент, переменная исчезнет.

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


переменные XSL строго ограничены, поэтому вы не можете получить к ним доступ в родственных узлах, только в дочерних. Если вы имеете дело с params, вы можете использовать global <xsl:param />.

см.:http://www.stylusstudio.com/xsllist/199911/post30020.html


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


если у вас есть переменная, вы можете проверить, что у нее есть что-то, или она "существует", выполнив что-то вроде следующего:

<xsl:choose>
    <xsl:when test="$myvar">
        This variable exists!
    </xsl:when>
    <xsl:otherwise>
        The variable doesn't exist :(
    </xsl:otherwise>
</xsl:choose>

что касается его действительности, я не могу быть уверен. Я скажу вам, однако, что я делаю это в некоторых наших системах на работе;)


лучшая и быстрая идея проверить walue, если он существует, - это проверить его длину

<xsl:if test="string-length(value/to/check)=0">

</xsl:if>

на любом языке программирования у вас будет точно такое же поведение.

Взять C#. попытка ссылаться на необъявленное имя переменной приводит к сообщению об ошибке. Это определенно ошибка программиста.

почему необходимо, чтобы XSLT вел себя по-другому?

Что касается размышлений о" До " и "позже" или о переменной, которая будет иметь более одного значения, чтобы обозначить, в каком "состоянии" мы находимся -- это все не разрешено в XSLT по определению - и именно отсутствие таких "функций" делает XSLT приятным и эллегантным функциональным языком.