如何用XSL检查一个值是空还是空?

例如,如果categoryName为空?我使用的是“当选择”结构。

例如:

<xsl:choose>
    <xsl:when test="categoryName !=null">
        <xsl:value-of select="categoryName " />
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="other" />
    </xsl:otherwise>
</xsl:choose>

当前回答

实际上,我发现它更好的只是测试字符串长度,因为很多时候字段不是空的,只是空的

< xsl:当测试= " - length (field-you-want-to-test) < 1 >

其他回答

如何用XSL检查一个值是空还是空? 例如,如果categoryName为空?

这可能是最简单的XPath表达式(accept answer中的表达式提供了相反的测试,如果否定,则会更长):

not(string(categoryName))

解释:

上面的not()函数的参数是false(),恰好当上下文项没有categoryName子项(“null”),或者(单个这样的)categoryName子项有字符串值——空字符串时。

我使用的是“当选择”结构。 例如: < xsl: choose > <xsl:when test="categoryName !=null"> <xsl:value-of select="categoryName " /> . < / xsl: when > < xsl:否则> <xsl:value-of select="other" /> . < / xsl:否则> < / xsl: choose >

在XSLT 2.0的使用中:

<xsl:copy-of select="concat(categoryName,  $vOther[not(string(current()/categoryName))])"/>

下面是一个完整的例子:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="vOther" select="'Other'"/>

 <xsl:template match="/">
  <xsl:copy-of select="concat(categoryName,$vOther[not(string(current()/categoryName))])"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于以下XML文档时:

<categoryName>X</categoryName>

生成所需的正确结果:

X

当应用于这个XML文档时:

<categoryName></categoryName>

或者关于这个:

<categoryName/>

或者在这个上面

<somethingElse>Y</somethingElse>

正确的结果是:

Other

类似地,使用以下XSLT 1.0转换:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:variable name="vOther" select="'Other'"/>

  <xsl:template match="/">
    <xsl:copy-of select=
    "concat(categoryName,  substring($vOther, 1 div not(string(categoryName))))"/>
  </xsl:template>
</xsl:stylesheet>

注意:完全没有使用条件句。在这个漂亮的Pluralsight课程中了解更多关于避免条件结构的重要性:

.NET中的战术设计模式:控制流

关于什么?

test="not(normalize-space(categoryName)='')"

来自Empty Element:

测试某个节点的值是否为空

这取决于你对空的定义。

不包含子节点:not(node()) 不包含文本内容:not(string(.)) 除空格外不包含任何文本:not(normalize-space(.)) 除了注释之外什么都不包含:not(node()[not(self::comment())])

根据我的经验,最好的方法是:

<xsl:when test="not(string(categoryName))">
    <xsl:value-of select="other" />
</xsl:when>
<otherwise>
    <xsl:value-of select="categoryName" />
</otherwise>

我知道这个问题已经很老了,但是在所有的答案中,我忽略了XSLT开发中这个用例的常用方法。

我想象OP中缺失的代码看起来像这样:

<xsl:template match="category">
    <xsl:choose>
        <xsl:when test="categoryName !=null">
            <xsl:value-of select="categoryName " />
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="other" />
        </xsl:otherwise>
    </xsl:choose>
</category>

输入是这样的:

<categories>
    <category>
       <categoryName>Books</categoryName>
    </category>
    <category>
       <categoryName>Magazines</categoryName>
       <categoryName>Periodicals</categoryName>
       <categoryName>Journals</categoryName>
    </category>
    <category>
        <categoryName><!-- please fill in category --></categoryName>
    </category>
    <category>
        <categoryName />
    </category>
    <category />
</categories>

I.e., I assume there can be zero, empty, single or multiple categoryName elements. To deal with all these cases using xsl:choose-style constructs, or in other words, imperatively, is quickly getting messy (even more so if elements can be at different levels!). A typical programming idiom in XSLT is using templates (hence the T in XSLT), which is declarative programming, not imperative (you don't tell the processor what to do, you just tell what you want output if certain conditions are met). For this use-case, that can look something like the following:

<!-- positive test, any category with a valid categoryName -->
<xsl:template match="category[categoryName[text()]]">
    <xsl:apply-templates />
</xsl:template>

<!-- any other category (without categoryName, "null", with comments etc) -->
<xsl:template match="category">
    <xsl:text>Category: Other</xsl:text>
</xsl:template>

<!-- matching the categoryName itself for easy handling of multiple names -->
<xsl:template match="categoryName">
    <xsl:text>Category: </xsl:text>
    <xsl:value-of select="." />
</xsl:template>

这是可行的(对于任何XSLT版本),因为上面的第一个具有更高的优先级(它有一个谓词)。“fall-through”匹配模板(第二个)捕获任何无效的内容。第三个函数负责以适当的方式输出categoryName值。

注意,在此场景中,不需要特别匹配类别或类别,因为处理器将自动处理所有子类,除非我们另有说明(在本例中,第二个和第三个模板不会进一步处理子类,因为它们中没有xsl:apply-templates)。

这种方法比命令式方法更容易扩展,因为它自动处理多个类别,并且可以通过添加另一个匹配模板来扩展其他元素或异常。没有if分支的编程。

注意:在XML中不存在空值。存在xsi:nil,但很少使用,特别是在没有某种模式的无类型场景中。