在XSLT中,如何测试变量是否存在?

时间:2009-08-19 13:04:40

标签: xml xslt

使用XSLT时,如何测试是否存在本地范围的变量,或者这是否可能?

7 个答案:

答案 0 :(得分:19)

将XSLT样式表视为XML DOM,变量声明元素使变量对所有后续兄弟及其后代可见。这允许XSLT处理器静态分析包含变量引用的任何XPath,以查看变量是否存在;如果变量声明存在于前兄弟或祖先轴上,则变量引用是合法的,否则不是。

请注意,这完全取决于XSLT的结构,而不是它正在处理的XML的结构。如果XPath表达式使用不存在的变量,XSLT处理器可以而且应该产生错误。

没有办法在XSLT中检查这种情况,因为这种情况在XSLT中是不合法的。您在评论中描述的静音 - “想法是设置一个标志变量,如果输出某些内容,稍后如果没有输出则显示不同的消息。” - 实际上应该导致语法错误。例如,如果您执行以下操作:

<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>

答案 1 :(得分:13)

提出这个问题表明你没有完全掌握XSLT的关键点。 : - )

它是声明性的:除非你声明它,否则什么都不存在。你声明一个变量,然后它就在那里,你没有,那就不是。

如果存在某个变量,那么在编码时你不得不怀疑这一点。

XSLT具有严格的范围规则,变量仅存在于其父元素的范围内(并且并非所有元素都可以包含要开始的变量)。离开父元素后,变量就消失了。

因此,除非您再详细说明您的问题/意图,否则唯一有效的答案是问题是错误的。您不能并且不需要检查运行时是否存在变量。

答案 2 :(得分:3)

XSL变量是严格限定的,因此您不能在兄弟节点中访问它们,只能在子节点中访问它们。 如果您正在处理params,则可以使用全局<xsl:param />

请参阅:http://www.stylusstudio.com/xsllist/199911/post30020.html

答案 3 :(得分:1)

我不认为这是可能的,但你不太可能需要它,因为除非你已经宣布变量,否则变量不存在。

答案 4 :(得分:1)

如果您有一个变量,您可以通过执行以下操作来检查它是否有某些内容,或者它是否“存在”:

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

至于其有效性,我无法确定。但是,我会告诉你,我在一些工作系统中这样做;)

答案 5 :(得分:1)

检查walue是否存在的最佳和快速的想法是检查它的长度

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

</xsl:if>

答案 6 :(得分:0)

在任何编程语言中,您都会有完全相同的行为。

使用C#。尝试引用未声明的变量名称会导致出现错误消息。这肯定是一个程序员错误。

为什么XSLT必须采用不同的行为

至于考虑“之前”和“之后”,或关于一个具有多个值的变量,以表示我们所处的“状态” - 根据定义,这在XSLT中是不允许的 - 并且正是缺少这样的“功能”才使得XSLT成为一种优秀而又优雅的功能语言。