迭代解析一个大的XML文件,而无需使用DOM方法

问题描述:

我有一个XML文件迭代解析一个大的XML文件,而无需使用DOM方法

<temp> 
    <email id="1" Body="abc"/> 
    <email id="2" Body="fre"/> 
    . 
    . 
    <email id="998349883487454359203" Body="hi"/> 
</temp> 

我想读的每一封电子邮件标记的XML文件。也就是说,一次我想读取电子邮件ID = 1 ...从中提取身体,读取电子邮件ID = 2 ...并从中提取身体...等等

我试图做到这一点使用DOM模型进行XML解析,因为我的文件大小为100 GB ..方法不起作用。我然后尝试使用:

from xml.etree import ElementTree as ET 
    tree=ET.parse('myfile.xml') 
    root=ET.parse('myfile.xml').getroot() 
    for i in root.findall('email/'): 
       print i.get('Body') 

现在,一旦我得到根..我不明白为什么我的代码不能解析。

在使用iterparse抛出下面的错误代码:

"UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 437: ordinal not in range(128)" 

有人可以帮

+0

您是否尝试过SAX解析? – Marcin 2012-04-06 07:28:58

+0

我试过了,但考虑到我的文件大小,我被建议使用'lxml',我也没有弄清楚如何使用iterparse。另外,谢谢你的回复。 :) – 2012-04-06 07:31:04

+0

你试过'xml.etree.ElementTree.iterparse()'? – Dikei 2012-04-06 07:32:02

一个例子iterparse:

import cStringIO 
from xml.etree.ElementTree import iterparse 

fakefile = cStringIO.StringIO("""<temp> 
    <email id="1" Body="abc"/> 
    <email id="2" Body="fre"/> 
    <email id="998349883487454359203" Body="hi"/> 
</temp> 
""") 
for _, elem in iterparse(fakefile): 
    if elem.tag == 'email': 
     print elem.attrib['id'], elem.attrib['Body'] 
    elem.clear() 

只需用实际文件替换fakefile。 另请参阅this了解更多详情。

+0

你忘了说'iterparse'应该来自哪里。 – 2012-04-06 08:13:02

+0

我添加了导入 – Dikei 2012-04-06 08:16:11

+0

+1,但对于100GB的文件,我会使用'iterparse'的LXML版本。 – 2012-04-06 08:33:17