【问题标题】:XML parsing using fast_iter clearing data before done processing使用 fast_iter 的 XML 解析在完成处理之前清除数据
【发布时间】:2023-01-31 16:52:03
【问题描述】:

我正在使用 Liza Daly 的 fast_iter,其结构如下:

def fast_iter(context, args=[], kwargs={}):
    """
    Deletes elements as the tree is travsersed to prevent the full tree from building and save memory
    Author: Liza Daly, IBM
    """
    for event, elem in context:
        if elem.tag == 'target':
            func(elem, *args, **kwargs)
            
            elem.clear()
        while elem.getprevious() is not None:
            del elem.getparent()[0]
    del context
    return save

但是,我注意到当我将上下文创建为

context = etree.iterparse(path, events=('end',))

elem 中的数据在我的函数甚至可以处理它之前就被删除了。为清楚起见,我使用的是完全同步的代码。

如果我将上下文设置为

context = etree.iterparse(path, events=('end',), tag='target')

它工作正常,但我知道它没有执行 fast_iter 旨在提供的完整内存保护。

与不创建树的 SAX 解析器 xml.dom.pulldom 相比,有什么理由甚至使用它吗?看起来 fast_iter 试图复制这个留在 lxml 中。

有没有人知道我做错了什么? TIA

【问题讨论】:

  • 凹凸可见性
  • 如果你设置了tag='target',你的代码就可以工作并且你得到了你想要的数据? “不做完整的内存保护”是什么意思?也许用一些示例来说明在访问数据之前以何种方式清除所需的数据,以及以何种方式使用tag='target' 不会给您带来想要的行为。
  • 我读到当你在 iterparse 中执行 tag='target' 时,它仍然会开发完整的树,尽管清除这是 fast_iter 的对立面
  • 您能否提供最少的样本来证明/允许其他人重现您的代码在函数可以处理之前删除数据?是否有任何嵌套的target 元素?兄弟姐妹?
  • 如果你清除,我认为完整的树不会被开发和保存,相反,如果你使用tag='foo'element.clear(),并保留context.root,你会得到一个包含祖先为foo的树的根元素和空/清除的foo 元素。假设大部分数据是每个 foo 的内容,这样内存占用应该比存储完整树要低得多。

标签: python xml parsing lxml


【解决方案1】:

我想我可以看到你的方法可能会在调用访问它的代码之前删除你想要访问的数据,让我们假设你有例如

<target>
  <foo>test</foo>
  <bar>test</bar>
</target>

您的 XML 中的元素,然后每次找到结束元素标记时您的代码

for event, elem in context:
    if elem.tag == 'target':
        func(elem, *args, **kwargs)
        
        elem.clear()
    while elem.getprevious() is not None:
        del elem.getparent()[0]

运行,这意味着它遇到 foo 结束元素标记,然后是 bar 结束元素标记,其中 while 循环删除了 foo 兄弟元素,然后遇到 target 结束元素标记,我假设你的函数看起来对于foobar 元素数据,但foo 元素已被删除。

因此,您的代码必须以某种方式考虑结构(您可能知道),并且不要在循环 target 元素的子/后代时这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多