gpt4 book ai didi

python-3.x - 尝试遍历 text() 节点以找到它们的父节点

转载 作者:行者123 更新时间:2023-12-04 10:42:04 25 4
gpt4 key购买 nike

假设我有以下示例 XML

<a>some <b>text</b> example</a>

使用 lxml让我以几种不同的方式查询文本节点:
>>> xml.xpath("//text()")
['some ', 'text', ' example']
>>> xml.xpath("//a/text()")
['some ', ' example']
>>> xml.xpath("//b/text()")
['text']

到目前为止,一切都很好(这些都是打印精美的 lxml.etree._ElementUnicodeResult 对象)。但是现在我想访问这些文本节点的父节点:
>>> xml.xpath("//text()/parent::*")
[<Element a at 0x10aa383c0>, <Element b at 0x10aa38410>]
>>> xml.xpath("//a/text()/parent::*")
[<Element a at 0x10aa383c0>]
>>> xml.xpath("//b/text()/parent::*")
[<Element b at 0x10aa38410>]
>>> xml.xpath("//*/text()/parent::*")
[<Element a at 0x10aa383c0>, <Element b at 0x10aa38410>]

作为典型的 XPath 操作,这些工作,我得到父节点的结果集。但我想遍历文本节点,然后获取它们各自的父节点:
>>> for e in xml.xpath("//text()"):
... print(e.xpath("./parent::*"))
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
AttributeError: 'lxml.etree._ElementUnicodeResult' object has no attribute 'xpath'

嗯,好吧,这似乎是 lxml 甚至底层 libxml2 的一个实现细节?但是 getparent() 去营救……还是?
>>> for e in xml.xpath("//text()"):
... print(f"'{e}'", e.getparent())
...
'some ' <Element a at 0x10aa383c0>
'text' <Element b at 0x10aa38410>
' example' <Element b at 0x10aa38410>

这让我感到困惑:在上面,在自上而下的搜索过程中,父节点对所有文本节点都有意义,自下而上它们是不同的: ' example'文本节点有父节点 ab ,取决于我如何查询其父级。

我是否遗漏了什么,或者这是一个错误(可能是由于 .text and .tail of element nodes

附录

看了之后 relevant lxml source code我认为内部 _elementStringResultFactory 需要修复;查看错误 1859435 .同时,以下解决方法给了我预期的结果:
>>> for e in xml.xpath("//text()"):
... p = e.getparent()
... print(f"'{e}'", p.getparent() if e.is_tail else p)
...
'some ' <Element a at 0x110799460>
'text' <Element b at 0x1100ad230>
' example' <Element a at 0x110799460>

最佳答案

根据 Stefan’s commentlxml bug report (现在标记为“无法修复”):

I consider this a feature. […]

Maybe "parent" isn't the ideal word. Maybe there could be better documentation, or an additional example in the docs somewhere. Doc PR welcome, but I don't think the behaviour should change.



所以,虽然这个特殊的 lxml 行为偏离了标准的 XML(见 Markus’ comment),但它是有意的。我在上面的 中使用的代码附录 我猜是访问文本节点的父节点的正确方法(即检查它们是否是 tail):
>>> for e in xml.xpath("//text()"):
... p = e.getparent()
... print(f"'{e}'", p.getparent() if e.is_tail else p)

关于python-3.x - 尝试遍历 text() 节点以找到它们的父节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59876655/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com