[英]Splitting a large XML file in Python
我希望将一个巨大的XML文件拆分成更小的位。 我想浏览文件以查找特定标记,然后获取之间的所有信息,然后将其保存到文件中,然后继续浏览文件的其余部分。
我的问题是试图找到一种干净的方式来记录标签的开始和结束,这样我就可以在我用“for line in f”扫描文件时抓取文本内部
我宁愿不使用sentinel变量。 是否有一种pythonic方法来完成这项工作?
该文件太大,无法读入内存。
处理XML数据有两种常用方法。
一个叫做DOM,代表文档对象模型。 这种XML解析风格可能就是您在查看文档时所看到的,因为它将整个XML读入内存以创建对象模型。
第二种叫做SAX,它是一种流式传输方法。 解析器开始读取XML并向代码发送有关某些事件的信号,例如,当找到新的开始标记时。
所以SAX显然是你所需要的。 Sax解析器可以在xml.sax和xml.parsers.expat下的python库中找到 。
您可以考虑在这种情况下使用ElementTree iterparse函数。
我已经成功使用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()
多么偶然! Larson是否会在Python中处理非常大的CSV和XML文件 。
正如Van所提到的,主要的xml.sax
是使用xml.sax
模块,并制作一些宏函数来抽象出低级SAX API的细节。
这是来自Uche Ogbuji的非常好的文章,也是非常好的Python和XMl专栏文章。 它涵盖了您的确切问题,并使用标准的lib的sax模块,就像其他答案所建议的那样。 分解,过程,重构
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.