检查XSLT中的字符串是否为空或为空




null xslt-1.0 (10)

如何使用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检查值是空还是空?

例如,如果categoryName是空的?

这可能是最简单的XPath表达式 (在接受的答案中提供了相反的测试,并且如果否定,则会更长):

not(string(categoryName))

说明

上面的not()函数的参数在上下文项没有categoryName子项(“null”)的情况下为false() ,或者(single)这样的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>

在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课程中避免条件结构的重要性:

app.pluralsight.com/library/courses/…


空的元素

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

这取决于你的意思是空的。

  • 不包含子节点: not(node())
  • 不包含文字内容: not(string(.))
  • 不包含除空白之外的文本: not(normalize-space(.))
  • 除注释外not(node()[not(self::comment())])包含任何内容: not(node()[not(self::comment())])

像这样的东西适合我:

<xsl:choose>
  <xsl:when test="string(number(categoryName)) = 'NaN'"> - </xsl:when> 
  <xsl:otherwise> 
    <xsl:number value="categoryName" />
  </xsl:otherwise>
</xsl:choose>

或者相反:

<xsl:choose>
  <xsl:when test="string(number(categoryName)) != 'NaN'">
    <xsl:number value="categoryName" />
  </xsl:when> 
  <xsl:otherwise> - </xsl:otherwise>
</xsl:choose>

注意:如果您不检查空值或处理空值,则IE7将返回-2147483648而不是NaN。


关于什么?

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

在某些情况下,您可能想知道该值何时特别为null,这在使用从.NET对象序列化的XML时尤为必要。 虽然接受的答案适用于此,但当字符串为空或空时,它也会返回相同的结果,即'',因此您无法区分。

<group>
    <item>
        <id>item 1</id>
        <CategoryName xsi:nil="true" />
    </item>
</group>

所以你可以简单地测试这个属性。

<xsl:if test="CategoryName/@xsi:nil='true'">
   Hello World.
</xsl:if>

有时候需要知道确切的状态,并且不能简单地检查CategoryName是否被实例化,因为不像说Javascript

<xsl:if test="CategoryName">
   Hello World.
</xsl:if>

将为null元素返回true。


在没有任何其他信息的情况下,我将假设以下XML:

<group>
    <item>
        <id>item 1</id>
        <CategoryName>blue</CategoryName>
    </item>
    <item>
        <id>item 2</id>
        <CategoryName></CategoryName>
    </item>
    <item>
        <id>item 3</id>
    </item>
    ...
</group>

示例用例如下所示:

<xsl:for-each select="/group/item">
    <xsl:if test="CategoryName">
        <!-- will be instantiated for item #1 and item #2 -->
    </xsl:if>
    <xsl:if test="not(CategoryName)">
        <!-- will be instantiated for item #3 -->
    </xsl:if>
    <xsl:if test="CategoryName != ''">
        <!-- will be instantiated for item #1 -->
    </xsl:if>
    <xsl:if test="CategoryName = ''">
        <!-- will be instantiated for item #2 -->
    </xsl:if>
</xsl:for-each>

如果元素不存在于XML中,我会测试元素是否存在,并且字符串长度是否大于零:

<xsl:choose>
    <xsl:when test="categoryName and string-length(categoryName) &gt; 0">
        <xsl:value-of select="categoryName " />
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="other" />
    </xsl:otherwise>
</xsl:choose>

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

<xsl:when test =“string-length(field-you-want-to-test)<1”>


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

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

test="categoryName != ''"

编辑 :这涵盖了最可能的解释,在我看来,从这个问题推断出来的“[not] null或empty”,包括它的伪代码和我自己早期的XSLT经验。 也就是说,“以下Java的等价物是什么?”:

!(categoryName == null || categoryName.equals(""))

有关更多详细信息,例如,明确识别空对空 ,请参阅下面的johnvey的答案和/或我从该答案改编的XSLT'小提琴' ,其中包括迈克尔凯评论中的选项以及第六种可能的解释。





xslt-2.0