我需要检查XML节点是否至少有一个非空子节点。应用于此XML表达式应返回true
<xml>
<node>
<node1/>
<node2/>
<node3>value</node3>
</node>
</xml>
我尝试使用此表达式:<xsl:if test="not(/xml/node/child::* = '')">
但似乎检查所有子项是否为空。
如果至少有一个元素不为空,我怎么能写一个返回true
的表达式?有没有办法在不创建另一个模板迭代节点chldren的情况下执行此操作?
UPD:我正在考虑计算非空节点,例如
test="count(not(/xml/node/child::* = '')) > '0'"
但不知何故只是无法让它正常工作。这个表达形式不是很好。
答案 0 :(得分:33)
更准确,更简单,更高效(无需使用count()
功能):
/*/node/*[text()]
如果要排除任何仅包含仅空白文本子元素的元素,请使用:
/*/node/*[normalize-space()]
答案 1 :(得分:11)
您只需要<xsl:if test="/xml/node/* != ''" />
。
在XPath中=
或!=
比较,其中一方是节点集,另一方是字符串成功,如果集合中的任何节点通过比较。因此
not(x = '')
表示“当前节点的任何x
子元素都不具有空字符串值”,这与
x != ''
表示“当前节点的至少一个x
子元素具有非空的字符串值”。特别是,如果要检查所有 x
个孩子是否为空,则需要使用“双阴性”测试
not(x != '')
答案 2 :(得分:4)
这是一个应该完成这项工作的XPath:
count(/*/node/*[text()]) > 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()]) > 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
。
答案 3 :(得分: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()) >0]!=''"/>
</xsl:template>
</xsl:stylesheet>
<强>解释强> 这将找到字符串长度大于零的第一个节点,然后将这些节点内容与空字符串进行比较(比较将返回非空字符串节点的存在);此代码还可用于在任何节点中查找特定条件,例如,标识包含特定字符串的节点的存在或以某个字符或任何其他条件开始;请将此作为节点参考的内部条件,以使代码发挥其神奇作用。