【问题标题】:XPath expression for finding the current element as well as children用于查找当前元素和子元素的 XPath 表达式
【发布时间】:2018-09-17 13:16:55
【问题描述】:

使用表达式.//b,我可以找到所有元素在当前元素的标签b。如果当前元素也有b 标签,则不会被找到。如果它与给定的标签名称匹配,我如何表达我想要找到当前标签的所有子标签以及当前元素本身?

这里是一些输入xml的例子:

<a>
  <b>
    <i>
      <u>one</u>
    </i>
    <b>two</b>
  </b>
  <b>three</b>
  <em>four</em>
</a>

如果第一个元素&lt;b&gt;是当前元素,我想获取所有子元素(即包含two的元素)和元素本身,但不是包含three的元素(搜索标签@ 987654328@)。在搜索标签u 时,我只想获取包含one 的标签。

我试过.[name()='b']|.//b,但这显然是一个无效的表达式。

我也尝试了..//b,但我不仅得到了元素本身和包含two的元素,还得到了包含three的元素。

这是否可以通过一个 XPath 表达式来获得我想要的?

旁注:我在 Python 的 lxml/etree 库中使用它,但这应该没什么区别。

【问题讨论】:

  • 尝试使用//b。使用.//b 毫无意义。 //b 应该给你带来 &lt;b&gt; 元素,里面有所有东西。
  • 不,.//b 很有意义,它的含义与//b 完全不同。信息错误!

标签: python xml xslt xpath lxml


【解决方案1】:

你想在这里使用descendant-or-self 轴:

descendant-or-self::b

或者,你可以这样做,写起来稍微短一些...

self::b|.//b

【讨论】:

  • 我现在使用(.|.//*)[name()='b'] 来避免标签名称加倍。但这基本上就是你的答案。
  • 稍微小心一点,因为name() 将返回任何命名空间前缀(因此,它不会匹配my:b 例如。在这种情况下您将使用local-name()。
  • 啊,不错。实际上,我正在使用ETXPath 类,它允许以所谓的克拉克表示法指定命名空间:{http://some/weird/uri}tagname。但是使用name() 仍然会产生带有前缀的名称,而不是克拉克符号:( 使用descendant-or-self:: 可以很好地与克拉克符号一起使用,所以我会坚持这样做以避免标签名称加倍。非常感谢!跨度>
  • 我肯定会选择descendant-or-self::b 作为最简单且最能表达意图的表达式。结构数量方面的简单性比字符数量方面的简洁性更重要。避免将name() 与字符串进行比较,这是一个坏习惯,有时会在性能方面付出高昂的代价。
  • 就我而言,性能不是问题,但总的来说你是对的。我只想要一个每次都能工作并且尽可能可读的版本。我同意详细限定符最适合这项任务。
猜你喜欢
  • 1970-01-01
  • 2018-07-09
  • 1970-01-01
  • 2021-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-25
相关资源
最近更新 更多