如果所有子项和孙子等都递归清空,XPath查询选择最高的空祖先?

时间:2015-09-07 10:53:04

标签: xml recursion xpath

' 为空'我的上下文中的标记被递归地定义为text()为空或者其所有子项都是' 为空'的那些标记。 在通用XML中,我们可以知道所有顶级' '标签?这是一个例子

<grand-parent>
  <parent1>
    <child1>v1</child1>
    <child2>v2</child2>
    <child3>v3</child3>
    <child4></child4>
  </parent1>
  <parent2>
    <child1>
     <gc></gc>
    </child1>
    <child2></child2>
  </parent2>
</grand-parent>

我需要节点child4parent2作为输出。我们可以使用XPath查询吗?

1 个答案:

答案 0 :(得分:2)

是的,你可以(假设XPath 1.0):

grand-parent//*[normalize-space(.) = ''][normalize-space(..) != '']

这符合以下原则:

  • grand-parent//表示来自grand-parent节点的递归,深度优先,文档顺序,所有后代或自我
  • *任何元素的缩写,在XPath 2.0中,这更清晰地写为element()。默认轴是子轴,因此它基本上是child::element()(或XPath 1.0中的child::*)的缩写,这意味着它选择当前元素上作为子元素的任何元素。由于我们从//开始,它会选择任何父级的任何子级。
  • [..]包含谓词,其中包含应用于当前节点的表达式。如果为true(如果是数字,则它是从当前轴上的第一个子节点开始的第x个节点),选择该节点。
  • .表示当前节点
  • normalize-space(.) = ''表示:删除任何双重空格或任何尾随或前导空格。雾化发生在.上,这实质上意味着:连接当前节点的所有子节点的所有文本值。换句话说:如果任何深度的任何孩子只存在空格,那就是这样。
  • ..表示:选择父节点。这是parent::node()的缩写,但实际上这总是选择一个元素或根(文档)节点,因为只有元素和文档节点可以有子节点。
  • normalize-space(..) != ''表示:雾化当前节点的父级(以及定义,也包括其所有子级和更深的后代)。如果在任何深度,这只包含空格,此谓词将返回false

一个相对简单的表达但很长的解释;)。你的要求的一个不变量是,如果一个元素是空的(按你的定义)并且它的父元素不是空的,那么它必须是(递归地)为空的最高元素。否则,父元素也将为空,最后一个谓词将返回false。