XSL / XPath expression to check if a node contains at least one non-empty child

前端 未结 4 571
小蘑菇
小蘑菇 2020-12-14 06:52

I need to check if an XML node has at least one non-empty child. Applied to this XML the expression should return true


    

        
相关标签:
4条回答
  • 2020-12-14 07:30

    Here's one XPath that should accomplish the job:

    count(/*/node/*[text()]) > 0
    

    When used in a sample XSLT:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:output omit-xml-declaration="yes" indent="yes"/>
      <xsl:strip-space elements="*"/>
    
      <xsl:template match="/">
         <xsl:value-of select="count(/*/node/*[text()]) &gt; 0" />
      </xsl:template>
    
    </xsl:stylesheet>
    

    ...which is, in turn, applied to the provided example XML:

    <xml>
      <node>
        <node1/>
        <node2/>
        <node3>value</node3>
      </node>
    </xml>
    

    ...the expected result is produced:

    true
    

    If we apply the same XSLT against a simply modified XML:

    <xml>
      <node>
        <node1/>
        <node2/>
        <node3/>
      </node>
    </xml>
    

    ...again, the expected result is produced:

    false
    

    Explanation:

    The XPath used searches for all children of a <node> element (which are, in turn, children of the root element) that have a non-empty text value (as specified by text()); should the count of such <node> children be greater than 0, then the XPath resolves to true.

    0 讨论(0)
  • 2020-12-14 07:48

    You just need <xsl:if test="/xml/node/* != ''" />.

    In XPath an = or != comparison where one side is a node set and the other side is a string succeeds if any of the nodes in the set passes the comparison. Thus

    not(x = '')
    

    means "it is not the case that any x child element of the current node has an empty string value", which is fundamentally different from

    x != ''
    

    which means "at least one x child element of the current node has a string value that is not empty". In particular, if you want to check that all x children are empty, you need to use a "double-negative" test

    not(x != '')
    
    0 讨论(0)
  • 2020-12-14 07:49
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <xsl:output omit-xml-declaration="yes" indent="yes"/>
        <xsl:strip-space elements="*"/>
        <xsl:template match="/">
            <xsl:value-of select="/*/node/*[string-length(text()) &gt;0]!=''"/>
        </xsl:template>
    </xsl:stylesheet>
    

    Explanation This will find the first node with a string length greater than zero and then compares such node contents with empty string (the comparison will return the existence of a non-empty string node); this code can also be used to look for a specific criteria in any node, for example identify the existence of a node which contains specific string or starts with some character or any other condition; please use this as the inner condition of the node reference for the code to work its magic.

    0 讨论(0)
  • 2020-12-14 07:53

    More accurate, simpler and more efficient (no need to use the count() function):

      /*/node/*[text()]
    

    If you want to exclude any element that has only whitespace-only text children, use:

      /*/node/*[normalize-space()]
    
    0 讨论(0)
提交回复
热议问题