Python 用于查找当前元素和子元素的XPath表达式

Python 用于查找当前元素和子元素的XPath表达式,python,xml,xslt,xpath,lxml,Python,Xml,Xslt,Xpath,Lxml,通过表达式//b我可以找到当前元素下带有标记b的所有元素。如果当前元素也有b标记,则将找不到它。如果当前元素与给定的标记名匹配,如何表示我希望找到当前标记的所有子元素以及当前元素本身 以下是一些输入xml的示例: <a> <b> <i> <u>one</u> </i> <b>two</b> </b> <b>three</b&

通过表达式
//b
我可以找到当前元素下带有标记
b
的所有元素。如果当前元素也有
b
标记,则将找不到它。如果当前元素与给定的标记名匹配,如何表示我希望找到当前标记的所有子元素以及当前元素本身

以下是一些输入xml的示例:

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

一
二
三
四
如果第一个元素
是当前元素,我希望获得所有子元素(即包含
两个
的元素)和元素本身,但不包括包含
三个
的元素(在搜索标记
b
时)。搜索标记
u
时,我只想得到包含
one
的标记

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

我还尝试了
。//b
,但我不仅得到了元素本身和包含
2
的元素,还得到了包含
3
的元素

用一个XPath表达式就可以得到我想要的东西吗


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

您想在这里使用
子体或self
轴:

descendant-or-self::b
或者,你可以这样做,这是稍微短写

self::b|.//b

您想在此处使用
子体或self
轴:

descendant-or-self::b
或者,你可以这样做,这是稍微短写

self::b|.//b

尝试使用
//b
。使用
//b
毫无意义
//b
应该将ou
元素及其内部的所有内容带到其中。不,
//b
非常有意义,其含义与
//b
大不相同。错误的信息!尝试使用
//b
。使用
//b
毫无意义
//b
应该将ou
元素及其内部的所有内容带到其中。不,
//b
非常有意义,其含义与
//b
大不相同。错误的信息!我现在使用
(.|.//*)[name()='b']
来避免标记名加倍。但这基本上就是您的答案。请稍微小心,因为
name()
将返回任何名称空间前缀(例如,它与
my:b
不匹配。您可以使用
local-name()
在这个例子中。啊,很好。实际上,我使用的是
ETXPath
类,它允许使用所谓的Clark表示法指定名称空间:
{http://some/weird/uri}标记名
。但使用
name()
仍会产生带有前缀的名称,而不是克拉克符号:(使用
genderant或self::
与Clark表示法配合使用很好,因此我将坚持使用这一点,以避免标记名加倍。非常感谢!我肯定会选择
genderant或self::b
作为最简单、最能表达意图的表达式。结构数量上的简单性比简洁性更重要n个字符数。避免比较
name()
与字符串相比,这是一个坏习惯,有时会让您付出高昂的性能代价。在我的情况下,性能不是问题,但一般来说,您是对的。我只想要一个每次都能工作且尽可能可读的版本。我同意详细限定符最适合此任务。我使用的是
(.|.//*)[name()='b']
现在避免将标记名加倍。但这基本上是您的答案。请稍微小心,因为
name()
将返回任何名称空间前缀(例如,它与
my:b
不匹配。您可以使用
local-name()
在这个例子中。啊,很好。实际上,我使用的是
ETXPath
类,它允许使用所谓的Clark表示法指定名称空间:
{http://some/weird/uri}标记名
。但使用
name()
仍会产生带有前缀的名称,而不是克拉克符号:(使用
genderant或self::
与Clark表示法配合使用很好,因此我将坚持使用这一点,以避免标记名加倍。非常感谢!我肯定会选择
genderant或self::b
作为最简单、最能表达意图的表达式。结构数量上的简单性比简洁性更重要n个字符数。避免比较
name()
与字符串相比,这是一个坏习惯,有时会让您付出高昂的性能代价。在我的情况下,性能不是问题,但总的来说,您是对的。我只想要一个每次都有效且尽可能可读的版本。我同意详细限定符最适合此任务。