在 Python 中分割大型 XML 文件

问题描述 投票:0回答:5

我希望将一个巨大的 XML 文件分割成较小的部分。我想扫描文件以查找特定标签,然后获取 和 之间的所有信息,然后将其保存到文件中,然后继续浏览文件的其余部分。

我的问题是试图找到一种干净的方法来记录标签的开始和结束,以便我可以在使用“for line in f”扫描文件时抓取其中的文本

我不想使用哨兵变量。有没有一种Python式的方法来完成这个任务?

文件太大,无法读入内存。

python xml
5个回答
9
投票

处理 XML 数据有两种常见方法。

其中一个称为 DOM,它代表文档对象模型。这种 XML 解析风格可能是您在查看文档时看到的,因为它将整个 XML 读取到内存中以创建对象模型。

第二种称为SAX,它是一种流式方法。解析器开始读取 XML 并向您的代码发送有关某些事件的信号,例如当找到新的开始标签时。

所以 SAX 显然是您所需要的。 Sax 解析器可以在 python 库中的 xml.saxxml.parsers.expat 下找到。


6
投票

我已经成功使用 cElementTree.iterparse 方法来完成类似的任务。

我有一个大型 xml 文档,其中包含带有标签“resFrame”的重复“条目”,我想过滤掉特定 id 的条目。这是我使用的代码:

源文档具有以下结构

<snapDoc>
  <bucket>....</bucket>
  <bucket>....</bucket>
  <bucket>....</bucket>
  ...
  <resFrame><id>234234</id>.....</resFrame>
  <frame><id>344234</id>.....</frame>
  <resFrame>...</resFrame>
  <frame>...</frame>
</snapDoc>

我使用以下脚本创建了一个较小的文档,该文档具有相同的结构、存储桶条目,并且只有具有特定 id 的 resFrame 条目。

#!/usr/bin/env python2.6

import xml.etree.cElementTree as cElementTree
start = '''<?xml version="1.0" encoding="UTF-8"?>
<snapDoc>'''

def main():
    print start
    context = cElementTree.iterparse('snap.xml', events=("start", "end"))
    context = iter(context)
    event, root = context.next() # get the root element of the XML doc

    for event, elem in context:
        if event == "end":
            if elem.tag == 'bucket': # i want to write out all <bucket> entries
               elem.tail = None  
               print cElementTree.tostring( elem )
            if elem.tag == 'resFrame':
                if elem.find("id").text == ":4:39644:482:-1:1": # i only want to write out resFrame entries with this id
                    elem.tail = None
                    print cElementTree.tostring( elem )
            if elem.tag in ['bucket', 'frame', 'resFrame']:
                root.clear()  # when done parsing a section clear the tree to safe memory
    print "</snapDoc>"

main()

6
投票

对于这种情况,您可以考虑使用 ElementTree iterparse 函数。


2
投票

多么偶然啊! Will Larson 刚刚发表了一篇关于 Handling Very Large CSV and XML File in Python.

的好文章。

主要的收获似乎是使用

xml.sax
模块,正如 Van 提到的,并创建一些宏函数来抽象低级 SAX API 的细节。


0
投票

这是一篇古老但非常好的文章,来自 Uche Ogbuji 也非常好的 Python & XMl 专栏。它涵盖了您的确切问题,并使用标准库的 sax 模块,就像其他答案所建议的那样。 分解、处理、重组

© www.soinside.com 2019 - 2024. All rights reserved.