代码之家  ›  专栏  ›  技术社区  ›  David542

改进node.xpath(//)

  •  0
  • David542  · 技术社区  · 5 年前

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

    node.xpath('//Parent')
    

    这将搜索 全部的 路径,以便找到 Parent 元素。然而,它只出现一次(尽管它可能出现在大约10个可能的路径上,写出来很乏味)。有没有一种方法可以在返回第一个元素时更有效地找到并退出,而不是在该路径上构建所有节点的列表?

    0 回复  |  直到 5 年前
        1
  •  3
  •   Mathias Müller    5 年前

    如果我理解正确,您不必使用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