在XSLT中,如何测试是否设置了变量?

时间:2018-04-04 12:36:46

标签: xml xslt xslt-1.0

使用XSLT时如何测试变量是否有值?或者更具体地说,如何正确嵌套下面的xsl:value-of方法,以便它返回''当没有分配值时,而不是未能转换?

声明选项可能是......

<xsl:variable name="ID" select="//MessageID"/>

<xsl:variable name="ID" select=""/>

需要添加什么才能使变换失败?

<Container>
  <xsl:attribute name="ID" select="$ID"/>
</Container>

期望的输出:

<Container ID=""/>

目前,如果变量的select语句没有找到引用的节点,则转换将失败。

我尝试了几种不同的方法:

<xsl:if test="$ID"><xsl:value-of select="$ID"/></xsl:if>

<xsl:if test="string-length($ID)&gt;0"><xsl:value-of select="$ID"/></xsl:if>

<xsl:if test="count($ID)&gt;0"><xsl:value-of select="$ID"/></xsl:if>

<xsl:if test="($ID) !=''"><xsl:value-of select="$ID"/></xsl:if>

我甚至尝试声明一个空变量进行比较:

<xsl:variable name="empty_string"/>

<xsl:if test="($ID) != $empty_string"><xsl:value-of select="$ID"/></xsl:if>

我发现这个问题非常相似,但明显不同于: In XSLT how do you test to see if a variable exists?

2 个答案:

答案 0 :(得分:1)

请尝试将<xsl:choose>放入变量中,如下所示:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="no"/>
    <xsl:template match="/">
        <xsl:variable name="ID">
            <xsl:choose>
                <!--check if path exists and if value is not empty-->
                <xsl:when test="//MessageID and string-length(//MessageID) &gt;0">
                    <xsl:value-of select="//MessageID"/>
                </xsl:when>
                <!--otherwise it will be assigned blank value-->
                <xsl:otherwise>
                    <xsl:value-of select="''"/>
                </xsl:otherwise>
            </xsl:choose>           
        </xsl:variable>
        <Container>
            <xsl:attribute name="ID">
                <xsl:value-of select="$ID"/>
            </xsl:attribute>
        </Container>   
    </xsl:template>    
</xsl:stylesheet>

所以如果输入:

<Main>
    <Test>
        <MessageID>123</MessageID>
    </Test>
</Main>

您的输出将是:<Container ID="123"/>

以下输入:

<?xml version="1.0" encoding="UTF-16"?>
<Main>
    <Test>
        <MessageID></MessageID>
    </Test>
</Main>

OR

<?xml version="1.0" encoding="UTF-16"?>
<Main>
    <Test>
    </Test>
</Main>

您的输出将是:<Container ID=""/>

希望它有所帮助。

答案 1 :(得分:0)

如果XSLT中存在变量,则它具有值。你问的是如何测试它是否有一些特殊的价值。

我通常鼓励人们避免像

这样的声明
<xsl:variable name="ID"><xsl:value-of select="//MessageID"/></xsl:variable>

支持

<xsl:variable name="ID" select="//MessageID"/>

因为它更简单,更快捷。但是我们假设你有一些很好的理由来使用更复杂的形式。在这种情况下,XSLT 1.0中的变量值将是一个“结果树片段”,其中包含单个文本节点子节点,或者在xsl:value-of指令创建零长度文本节点的情况下根本不包含子节点

您可以通过测试<xsl:if test="string($ID)"/>来测试结果树片段的字符串值是否为零长度。但是,这也将返回false,例如,对于RTF,其内容是具有零长度字符串值的元素节点。

不幸的是,如果不使用node-set()扩展函数,你不能对RTF做很多事情。如果您可以访问node-set()扩展函数,则可以执行哪些测试,以确定RTF的根节点是否具有子节点。一切都非常混乱。

建议:

(a)尽可能使用xsl:variable与[{1}}属性绑定的形式。

(b)现在不是你搬到XSLT 2.0 +了吗?