【问题标题】:XSL / XPath expression to check if a node contains at least one non-empty childXSL / XPath 表达式检查节点是否包含至少一个非空子节点
【发布时间】:2015-07-28 02:00:10
【问题描述】:

我需要检查一个 XML 节点是否至少有一个非空子节点。应用于此 XML 的表达式应返回 true

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

我尝试使用这个表达式:&lt;xsl:if test="not(/xml/node/child::* = '')"&gt;,但它似乎检查 all 孩子是否不为空。

如果至少一个元素不为空,我如何编写返回true 的表达式?有没有办法在不创建另一个模板来迭代节点 chldren 的情况下做到这一点?

UPD:我正在考虑计算非空节点,例如
test="count(not(/xml/node/child::* = '')) &amp;gt; '0'"
但不知何故无法让它正常工作。这个表达式不是格式正确的。

【问题讨论】:

    标签: xml xslt xpath


    【解决方案1】:

    更准确、更简单、更高效(无需使用count()函数)

      /*/node/*[text()]
    

    如果您想排除任何只有空白文本子元素的元素,请使用:

      /*/node/*[normalize-space()]
    

    【讨论】:

    • 你碰巧知道我如何测试“如果不是一个孙子term(无论父元素叫什么)包含字符串','”吗?我试过record[not(contains(*/*/term, ','))],但它匹配了第一个term没有','的记录,第二个有(逻辑上似乎错过了any / none方面)。
    • 先生,为漂亮的 Xpath 表达式 +1。
    【解决方案2】:

    你只需要&lt;xsl:if test="/xml/node/* != ''" /&gt;

    在 XPath 中,如果集合中的 任何 个节点通过比较,则一侧是节点集而另一侧是字符串的 =!= 比较成功。因此

    not(x = '')
    

    意思是“当前节点的任何x子元素都不会有空字符串值”,与

    有本质区别
    x != ''
    

    表示“当前节点的至少一个x子元素的字符串值不为空”。特别是,如果要检查 all x children 是否为空,则需要使用“双阴性”测试

    not(x != '')
    

    【讨论】:

    • 这是非常宝贵的编程知识之一,可以为您节省数小时的压力。
    【解决方案3】:

    这是一个可以完成这项工作的 XPath:

    count(/*/node/*[text()]) &gt; 0
    

    在示例 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>
    

    ...依次应用于提供的示例 XML:

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

    ...产生了预期的结果:

    true
    

    如果我们对简单修改的​​ XML 应用相同的 XSLT:

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

    ...再次产生预期的结果:

    false
    

    说明:

    使用的 XPath 搜索 &lt;node&gt; 元素的所有子元素(它们又是根元素的子元素)具有非空文本值(由 text() 指定);如果此类&lt;node&gt; 子级的计数大于0,则XPath 解析为true

    【讨论】:

    • 哦,text().. 我知道我错过了什么!谢谢。
    【解决方案4】:
    <?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>
    

    说明 这将找到字符串长度大于零的第一个节点,然后将此类节点内容与空字符串进行比较(比较将返回非空字符串节点的存在);此代码还可用于在任何节点中查找特定条件,例如识别是否存在包含特定字符串或以某个字符或任何其他条件开头的节点;请将此作为节点引用的内部条件,以便代码发挥其魔力。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-24
      • 2021-06-09
      • 1970-01-01
      • 2011-11-20
      • 1970-01-01
      相关资源
      最近更新 更多