改进 node.xpath('//')

Improving node.xpath('//')

我发现自己正在执行以下操作来查找可能出现在多个 xpath 中的一个节点,但该节点本身只会出现一次:

node.xpath('//Parent')

这将搜索 所有 路径以找到 Parent 元素。但是,它只出现一次(尽管它可能出现在 10 条左右的可能路径上,而且写起来非常乏味)。有没有一种我可以使用的方法可以在返回第一个元素时更有效地找到并退出,而不是构建该路径上所有节点的列表?

如果我没理解错的话,您不必使用 XPath 并且可以通过名称来识别有问题的元素。然后您可以使用 event-driven parsing - 也称为 "SAX" 解析 - 而不是 lxml 默认执行的常规 "DOM" 解析。

代码类似于(伪代码)

some_file_like = BytesIO(b"<root><a>data</a></root>")
for event, element in etree.iterparse(some_file_like):
    if element.tag == "Parent":
        act_on(element)
        break

或者,一种非常相似的方法是在 Python 中使用 SAX 解析器实现,例如 https://docs.python.org/3/library/xml.sax.reader.html。这将使您对解析有更细粒度的控制,因为您将编写在遇到特定类型的事件时执行的自定义回调。

一个例子,改编自here

from xml.sax import saxutils, handler, make_parser

class ContentGenerator(handler.ContentHandler):

    def __init__(self, out = sys.stdout):
        handler.ContentHandler.__init__(self)

    def startDocument(self):
        pass

    def startElement(self, name, attrs):
        if name == "Parent":
            # act on this element