在Python中拆分大型XML文件

时间:2009-01-25 00:22:01

标签: python xml

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

我的问题是试图找到一种干净的方式来记录标签的开头和结尾,这样我就可以在我用“for line in f”扫描文件时抓取文本内部

我宁愿不使用哨兵变量。是否有一种pythonic方式来完成这项工作?

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

5 个答案:

答案 0 :(得分:9)

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

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

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

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

答案 1 :(得分:6)

您可以考虑在这种情况下使用ElementTree iterparse函数。

答案 2 :(得分: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>

我使用以下脚本创建了一个较小的doc,它具有相同的结构,bucket条目和只有具有特定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()

答案 3 :(得分:1)

多么偶然!拉尔森会发表一篇关于Handling Very Large CSV and XML File in Python的好文章。

正如Van所提到的,主要的好处是使用xml.sax模块,并制作一些宏函数来抽象出低级SAX API的细节。

答案 4 :(得分:0)

这是一篇古老而又非常好的文章,来自Uche Ogbuji的非常好的Python&amp; XMl列。它涵盖了您的确切问题,并使用标准的lib的sax模块,就像其他答案所建议的那样。 Decomposition, Process, Recomposition