XSL / XPath表达式用于检查节点是否包含至少一个非空子节点

29

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

<xml>
    <node>
       <node1/>
       <node2/>
       <node3>value</node3>
    </node>
</xml>
我尝试使用这个表达式:<xsl:if test="not(/xml/node/child::* = '')">,但它似乎检查的是所有子元素是否都为空。
我该如何编写一个表达式,在至少有一个元素不为空时返回true?是否有方法可以在不创建另一个模板来迭代节点的情况下完成这个任务? 更新:我正在考虑计算非空节点,例如
test="count(not(/xml/node/child::* = '')) &gt; '0'"
但无论如何我都无法使其正常工作。该表达式不符合规范。
4个回答

35

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

  /*/node/*[text()]

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

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

你知道我怎么测试“如果没有一个子元素term(无论父元素叫什么)包含字符串','”吗?我尝试了record[not(contains(*/*/term, ','))],但它匹配了第一个term没有','的记录,而第二个有(似乎逻辑上错过了任何 / 的方面)。 - CodeManX
先生,赞一个漂亮的XPath表达式。 - Rudramuni TP

12

你只需要使用<xsl:if test="/xml/node/* != ''" />

在XPath中,若一个比较表达式的一侧是节点集合,另一侧是字符串,则当该节点集合中任意一个节点通过了比较,比较就会成功。

not(x = '')

意味着"当前节点的任何x子元素都不具有空字符串值",这与

x != ''

这意味着“当前节点至少有一个子元素x的字符串值不为空”。特别是,如果您想检查所有x子元素是否都为空,则需要使用“双重否定”测试。

not(x != '')

这是一项非常宝贵的编程知识,可以为你节省数小时的压力。 - Sandy Gifford

4
这里有一个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搜索一个<node>元素的所有子元素(这些子元素是根元素的子元素),并且这些子元素有非空文本值(由text()指定);如果此类<node>子元素的数量大于0,则XPath解析为true


哦,text().. 我知道我错过了什么!谢谢。 - svz

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接