我怎么可以检查,如果一个值为空或空白带 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>
有帮助吗?

解决方案

test="categoryName != ''"

修改:在我看来,这涵盖了最可能的解释<!>“; [not] null或空<!>;从问题推断,包括它的伪代码和我自己的XSLT早期经验。即,<!>“以下Java的等价物是什么?<!>”:

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

有关详细信息,例如,清楚地标识null与空,请参阅下面的 johnvey的答案和/或 XSLT'小提琴'我改编自这个答案,其中包括Michael Kay评论中的选项以及第六个可能的选项解释

其他提示

如果没有任何其他信息,我将假设以下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>

空元:

测试,如果该价值的一定的节点是空的

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

  • 没有包含儿童节点: not(node())
  • 含有文字内容: not(string(.))
  • 没有包含的文本比其他的空白: not(normalize-space(.))
  • 含有什么,除了评论: not(node()[not(self::comment())])

怎么样?

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

前两个处理空值,第二个处理空字符串。

<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>

在某些情况下,您可能想知道值何时特别为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中可能存在元素,我会测试元素是否存在以及字符串长度是否大于零:

<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>

我知道这个问题很老,但在所有答案之间,我想念一个在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版本),因为上面的第一个具有更高的优先级(它有一个谓词)。 <!> quot; fall-through <!>匹配模板,第二个,捕获任何无效的。第三个然后负责以适当的方式输出categories值。

请注意,在这种情况下,不需要特别匹配categoryxsl:apply-templates,因为处理器将自动处理所有子项,除非我们另外说明(在此示例中,第二个和第三个模板不再进一步)处理孩子,因为他们没有null

这种方法比命令式方法更容易扩展,因为它自动处理多个类别,只需添加另一个匹配模板就可以扩展其他元素或异常。 没有if-branches编程

注意:XML中没有<=>这样的东西。有 xsi:nil ,但很少使用,特别是很少用于无类型没有某种模式的场景。

  

如何使用XSL检查值是空还是空?

     

例如,如果categoryName为空?

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

not(string(categoryName))

<强>解释

上面not()函数的参数是false(),当上下文项没有<=>子(<!> quot; null <!>;)时,或者(单个这样的)< => 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课程中了解更多关于避免条件结构的重要性:

<! >“ .NET中的战术设计模式:控制流程 <!>”

如果节点在输入xml中没有可用值,如xpath,

<node>
    <ErrorCode/>
</node>

string()函数转换为空值。所以这很好用:

string(/Node/ErrorCode) =''

这样的事情对我有用:

<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。

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

  

<!> lt; xsl:when test = <!> quot; string-length(field-you-want-to-test)<!> lt; 1 <!> quot; <!> gt;

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

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

使用简单的categoryName / text()此类测试适用于<categoryName/><categoryName></categoryName>

<xsl:choose>
    <xsl:when test="categoryName/text()">
        <xsl:value-of select="categoryName" />
    </xsl:when>
    <xsl:otherwise>
        <xsl:value-of select="other" />
    </xsl:otherwise>
</xsl:choose>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top