如何在XSLT中判断变量是否有值

20

我正在创建XSLT文件。 我有一个变量,它从XML文件中获取值。但是,可能会出现在xml中没有对该值的引用,并且此时XSL变量将返回False/None(不确定)的情况。我想保持这样的条件,如果变量没有值,则使用默认值。 要如何实现?


可能是重复的问题:在 XSLT 中如何测试变量是否存在? - Chris Page
5个回答

33

根据问题所给的少量细节,您可以进行的最简单测试是:

<xsl:if test="$var">
    ...
</xsl:if>

如果你想要为else情况提供输出,你可以使用xsl:choose

<xsl:choose>
    <xsl:when test="not($var)"> <!-- parameter has not been supplied -->
</xsl:when>
    <xsl:otherwise> <!--parameter has been supplied --> </xsl:otherwise>
</xsl:choose>
第二个示例还将正确处理变量或参数未提供实际值的情况,即它等于空字符串。这是因为not('')返回true

4
如果测试变量的内容而不是存在性,那么使用 test="$var != ''" 可能会更好一些。 - scunliffe
1
我支持@scunliffe的观点 - 如果$var存在但为空,test="$var"仍将返回true。然而,如果您使用早期版本的XSL,则可能需要编写test="not($var = '')" - Scott Baker
@scunliffe:请查看我的扩展答案,以处理空字符串。 - Dirk Vollmar
@0xA3:你写道:“还要正确处理变量根本没有被设置的情况”。在XSLT语言中是不存在这种情况的。变量总是“被设置”的。请查看我的回答。 - user357812
@Alejandro:我的措辞不够精确,但是在某些情况下可能无需显式地为变量/参数选择一个值,此时该变量将采用空字符串作为默认值。 - Dirk Vollmar
@0xA3:参数完全是另一回事。它们如此重要,以至于默认值问题应该用其他方式处理。 - user357812

16

您没有解释"无值"是什么意思。这里有一个通用解决方案:

not($v) and not(string($v))

如果$v“没有值”,则该表达式评估为true()

两个条件都需要满足,因为一个字符串$v被定义为'0'具有一个值,但是not($v)true()

在XSLT 1.0中,如果“值”是节点集或标量(例如字符串、数字或布尔值),可以通过不同的方式实现默认值。

@Alejandro提供了一种获取默认值的方法,如果变量应该包含空的节点集。

如果变量应该包含标量,则以下表达式返回其值(如果它具有值)或(否则)所需的默认值:

concat($v, substring($default, 1 div (not($v) and not(string($v)))))

一个变量怎么可能没有被设置,即使它是标量值?只有参数可能没有被设置(且没有默认表达式)。只有在这种情况下,参数才会取空字符串作为值。 - user357812
@Alejandro:根据点11.,变量可能绑定到一个值。如果没有通过select属性或变量绑定元素的内容明确提供值,则点11.2的第三个项目适用于将变量绑定到空字符串。 - Dirk Vollmar
1
@0xA3:它说“变量绑定元素可以用三种不同的方式指定变量的值”,第三种方式是“变量绑定元素没有内容且没有选择属性,则变量的值为空字符串”。因此,它有一个明确定义的值。不存在没有值的情况。 - user357812

6
你可以使用 string-length 函数来检查变量 $reference 是否包含任何内容,例如。
<xsl:choose>

  <xsl:when test="string-length($reference) > 0">
    <xsl:value-of select="$reference" />
  </xsl:when>

  <xsl:otherwise>
    <xsl:text>some default value</xsl:text>
  </xsl:otherwise>

</xsl:choose>

如果必要,也可以使用normalize-space函数。

不错。如果您正在检查 XML 中的参数,请注意使用 normalize-space。需要删除回车符。 - Faliorn

0
首先,所有的变量都有值,因为XSLT属于声明式范式:没有赋值指令,但是当你声明变量时,同时也在声明其值关系的表达式。
如果这个值是一个节点集数据类型(根据你的问题看起来是这样),那么在未选中任何内容时,你应该测试是否为空节点集。空节点集的有效布尔值为false。所以,如@0xA3所回答的那样:test="$node-set"
你写道:

如果变量没有值 使用默认值。怎么做呢?

嗯,这取决于你要寻找什么类型的数据。
假设是节点集数据类型:如果你想要$node-set-1的值,或者如果$node-set-1为空,则使用$node-set-2的值,那么可以使用以下代码:
$node-set-1|$node-set-2[not($node-set-1)]

@Alejandro:这是一个很好的答案,但OP没有表明该值是要保存一个节点集。它可能只是一个字符串... - Dimitre Novatchev
@Dimitre:说得好。我是这样读这句话的:“我有一个变量,它从XML文件中获取值”。 - user357812

0

我尝试了很多来自SO的解决方案,我的最后一个解决方案是从@dimitre-novatchev那里得到的,但有时候它也不起作用。最近我在随机谷歌搜索中发现了另一种解决方案,想与社区分享。

为了检查空变量值,我们可以声明一个空变量并将其值与测试条件进行比较。以下是代码片段:

<xsl:variable name="empty_string"/>
<xsl:if test="testVariableValue != $empty_string">
...
</xsl:if>

这里的testVariableValue保存了要测试空场景的新变量的值。 希望它能帮助测试空变量状态。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接