获取属性的 XPath

Get XPath to attribute

我想获取 xml 元素树中特定属性的属性节点的实际 XPath 表达式(使用 lxml)。

假设下面的 XML 树。

<foo>
  <bar attrib_name="hello_world"/>
</foo>

XPath 表达式“//@*[local-name() = "attrib_name"]”生成 ['hello_world'],这是相关属性的值,而“//@*[ local-name() = "attrib_name"]/.." 给我 bar 元素,它太高了一层,我需要特定属性节点本身的 xpath 表达式,而不是它的父 xml 节点,即具有字符串 'attrib_name' 我想生成 '/foo/bar/@attrib_name'.

from lxml import etree
from io import StringIO

f = StringIO('<foo><bar attrib_name="hello_world"></bar></foo>')
tree = etree.parse(f)

print(tree.xpath('//@*[local-name() = "attrib_name"]'))
# --> ['hello_world']
print([tree.getpath(el) for el in tree.xpath('//@*[local-name() = "attrib_name"]/..')])
# --> ['/foo/bar']

作为附加组件,它也应该适用于命名空间。

如果你删除 /.. 那么你将得到 _ElementUnicodeResult

这将允许您将属性名称附加到 xpath:

>>> print(['%s/@%s' % (tree.getpath(attrib_result.getparent()), attrib_result.attrname) for attrib_result in tree.xpath('//@*[local-name() = "attrib_name"]')])
['/foo/bar/@attrib_name']

尝试将其应用于名称空间将导致名称空间添加到 xpath(这可能不是您想要的):

>>> tree = etree.parse(StringIO('<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><bar xsi:attrib_name="hello_world"></bar></foo>'))
>>> print(['%s/@%s' % (tree.getpath(attrib_result.getparent()), attrib_result.attrname) for attrib_result in tree.xpath('//@*[local-name() = "attrib_name"]')])
['/foo/bar/@{http://www.w3.org/2001/XMLSchema-instance}attrib_name']