如何使用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>
答案 0 :(得分:309)
test="categoryName != ''"
编辑:在我看来,这涵盖了最有可能的解释,从问题中推断出“[not] null或empty”,包括它的伪代码和我自己的XSLT早期经验。即,“以下Java的等价物是什么?”:
!(categoryName == null || categoryName.equals(""))
有关详细信息,例如明确标识null与空,请参阅johnvey's answer below和/或the XSLT 'fiddle'我已根据该答案进行了调整,其中包括Michael Kay评论中的选项以及第六个可能的解释。
答案 1 :(得分:260)
如果没有任何其他信息,我将假设以下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>
答案 2 :(得分:63)
来自 Empty Element :
测试某个节点的值是否为空
这取决于你的意思是空的。
not(node())
not(string(.))
not(normalize-space(.))
not(node()[not(self::comment())])
答案 3 :(得分:21)
怎么样?
test="not(normalize-space(categoryName)='')"
答案 4 :(得分:9)
前两个处理空值,第二个处理空字符串。
<xsl:if test="USER/FIRSTNAME">
USERNAME is not null
</xsl:if>
<xsl:if test="not(USER/FIRSTNAME)">
USERNAME is null
</xsl:if>
<xsl:if test="USER/FIRSTNAME=''">
USERNAME is empty string
</xsl:if>
<xsl:if test="USER/FIRSTNAME!=''">
USERNAME is not empty string
</xsl:if>
答案 5 :(得分:5)
在某些情况下,您可能想知道值何时特别为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。
答案 6 :(得分:4)
如果XML中可能存在元素,我会测试元素是否存在以及字符串长度是否大于零:
<xsl:choose>
<xsl:when test="categoryName and string-length(categoryName) > 0">
<xsl:value-of select="categoryName " />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="other" />
</xsl:otherwise>
</xsl:choose>
答案 7 :(得分:4)
我知道这个问题很老,但在所有答案之间,我想念一个在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>
即,我假设可以有零,空,单个或多个categoryName
元素。使用xsl:choose
样式结构来处理所有这些情况,或者换句话说,强制性地,很快就会变得混乱(如果元素可以处于不同的级别,则更是如此!)。 XSLT中的典型编程习惯是使用模板(因此是XSLT中的T),这是声明式编程,而不是命令式的(您不告诉处理器该做什么,只要满足某些条件就告诉您想要输出什么)。对于此用例,可能如下所示:
<!-- 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版本),因为上面的第一个具有更高的优先级(它有一个谓词)。第二个“直通”匹配模板捕获任何无效的匹配模板。然后第三个以适当的方式输出categoryName
值。
请注意,在这种情况下,不需要特别匹配categories
或category
,因为处理器将自动处理所有子节点,除非我们另有说明(在此示例中,第二个和第三个)模板不会进一步处理子项,因为它们中没有xsl:apply-templates
。
这种方法比命令式方法更容易扩展,因为它自动处理多个类别,并且可以通过添加另一个匹配模板来扩展其他元素或异常。 没有if-branches编程。
注意:XML中没有null
这样的东西。有xsi:nil,但很少使用,特别是在没有某种模式的无类型场景中很少使用。
答案 8 :(得分:3)
如果节点在输入xml中没有可用值,如xpath,
<node>
<ErrorCode/>
</node>
string()函数转换为空值。所以这很好用:
string(/Node/ErrorCode) =''
答案 9 :(得分:3)
如何使用XSL检查值是空还是空?
例如,如果
categoryName
为空?
这可能是最简单的XPath表达式(接受答案中的那个提供相反的测试,如果否定则会更长):
not(string(categoryName))
<强>解释强>:
上面的not()
函数的参数是false()
,正好是上下文项没有categoryName
子项(&#34; null&#34;)或者(单个)这样)categoryName
child有字符串值 - 空字符串。
我在选择构造时使用。
例如:
<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课程中了解更多关于避免条件结构的重要性:
答案 10 :(得分:2)
这样的事情对我有用:
<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。
答案 11 :(得分:0)
根据我的经验,最好的方法是:
<xsl:when test="not(string(categoryName))">
<xsl:value-of select="other" />
</xsl:when>
<otherwise>
<xsl:value-of select="categoryName" />
</otherwise>
答案 12 :(得分:0)
我实际上发现它只是测试字符串长度更好,因为很多时候字段不为空,只是空
&lt; xsl:when test =&#34; string-length(field-you-to-test)&lt; 1&#34;&gt;