Check if a string is null or empty in XSLT

前端 未结 14 995
梦毁少年i
梦毁少年i 2020-11-27 09:12

How can I check if a value is null or empty with XSL?

For example, if categoryName is empty? I\'m using a when choosing construct.

For

相关标签:
14条回答
  • 2020-11-27 09:47

    How can I check if a value is null or empty with XSL?

    For example, if categoryName is empty?

    This is probably the simplest XPath expression (the one in accepted answer provides a test for the opposite, and would be longer, if negated):

    not(string(categoryName))
    

    Explanation:

    The argument to the not() function above is false() exactly when there is no categoryName child ("null") of the context item, or the (single such) categoryName child has string value -- the empty string.

    I'm using a when choosing construct.

    For example:

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

    In XSLT 2.0 use:

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

    Here is a complete example:

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

    When this transformation is applied on the following XML document:

    <categoryName>X</categoryName>
    

    the wanted, correct result is produced:

    X
    

    When applied on this XML document:

    <categoryName></categoryName>
    

    or on this:

    <categoryName/>
    

    or on this

    <somethingElse>Y</somethingElse>
    

    the correct result is produced:

    Other
    

    Similarly, use this XSLT 1.0 transformation:

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

    Do note: No conditionals are used at all. Learn more about the importance of avoiding conditional constructs in this nice Pluralsight course:

    "Tactical Design Patterns in .NET: Control Flow"

    0 讨论(0)
  • 2020-11-27 09:51

    If there is a possibility that the element does not exist in the XML I would test both that the element is present and that the string-length is greater than zero:

    <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>
    
    0 讨论(0)
  • 2020-11-27 09:54
    test="categoryName != ''"
    

    Edit: This covers the most likely interpretation, in my opinion, of "[not] null or empty" as inferred from the question, including it's pseudo-code and my own early experience with XSLT. I.e., "What is the equivalent of the following Java?":

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

    For more details e.g., distinctly identifying null vs. empty, see johnvey's answer below and/or the XSLT 'fiddle' I've adapted from that answer, which includes the option in Michael Kay's comment as well as the sixth possible interpretation.

    0 讨论(0)
  • 2020-11-27 09:58

    What about?

    test="not(normalize-space(categoryName)='')"
    
    0 讨论(0)
  • 2020-11-27 10:02

    Absent of any other information, I'll assume the following 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>
    

    A sample use case would look like:

    <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>
    
    0 讨论(0)
  • 2020-11-27 10:02

    If a node has no value available in the input xml like below xpath,

    <node>
        <ErrorCode/>
    </node>
    

    string() function converts into empty value. So this works fine:

    string(/Node/ErrorCode) =''
    
    0 讨论(0)
提交回复
热议问题