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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13703478/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 13:48:39  来源:igfitidea点击:

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

xmlxsltxpath

提问by svz

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

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

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

I tried to use this expression: <xsl:if test="not(/xml/node/child::* = '')">but it seems to check if allchildren are not empty.

我尝试使用这个表达式:<xsl:if test="not(/xml/node/child::* = '')">但它似乎检查是否所有孩子都不是空的。

How can I write an expression which returns trueif at least oneelement is not empty? Is there a way to do this without creating another template to iterate over node chldren?

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

UPD:I'm thinking of counting non-empty nodes like
test="count(not(/xml/node/child::* = '')) &gt; '0'"
but somehow just can't make it work right. This expression is not a well-formed one.

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

回答by Dimitre Novatchev

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

更准确、更简单、更高效(无需使用该count()功能)

  /*/node/*[text()]

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

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

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

回答by Ian Roberts

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

你只需要<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 anyof the nodes in the set passes the comparison. Thus

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

not(x = '')

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

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

x != ''

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

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

not(x != '')

回答by ABach

Here's one XPath that should accomplish the job:

这是一个应该完成这项工作的 XPath:

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

When used in a sample XSLT:

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

<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 应用相同的 XSLT:

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

使用的 XPath 搜索<node>具有非空文本值(由 指定text())的元素的所有子元素(这些子元素又是根元素的子元素);如果此类<node>子项的计数大于 0,则 XPath 解析为true

回答by HectorYep

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

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

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