使用XSLT时,如何测试是否存在本地范围的变量,或者这是否可能?
答案 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成为一种优秀而又优雅的功能语言。