1

我正在尝试解析一个大的 xml文件并将标签打印到输出文件。我正在使用minidom,我的代码对于 30Mb 文件运行良好,但对于较大的文件,它会出现内存错误。所以我使用缓冲读取文件,但现在我无法获得所需的输出。

XML 文件

> <File> <TV>Sony</TV> <FOOD>Burger</FOOD> <PHONE>Apple</PHONE> </File>   
> <File> <TV>Samsung</TV> <FOOD>Pizza</FOOD> <PHONE>HTC</PHONE> </File>  
> <File> <TV>Bravia</TV> <FOOD>Pasta</FOOD> <PHONE>BlackBerry</PHONE> </File>  

期望的输出

索尼、汉堡、苹果
三星、披萨、HTC
Bravia、意大利面、黑莓

使用缓冲区阅读时,它给了我一个输出:-
Sony,Burger,Apple
Samsung,Piz Bravia,Pasta,BlackBerry

while 1:
    content = File.read(2048)
        if not len(content):
            break
         else:
             for lines in StringIO(content):
                lines = lines.lstrip(' ')
                if lines.startswith("<TV>"):
                   TV =  lines.strip("<TV>")
                   tvVal = TV.split("</TV>")[0]
                   #print tvVal
                   w2.writelines(str(tvVal)+",")
                elif lines.startswith("<FOOD>"):
                   FOOD =  lines.strip("<FOOD>")
                   foodVal = FOOD.split("</FOOD>")[0]
                   #print foodVal
                   w2.writelines(str(foodVal)+",")
                   ............................
                   ...........................

我尝试使用seek()但仍然无法获得所需的输出。

4

2 回答 2

1

您一次读取 2048 个字节,这会将读取光标放在一行的中间。在下一次读取中,该行的其余部分被丢弃,因为它不是以标签开头。

与其滚动您自己的解析器,不如考虑使用iterparse. 下面是一个示例,iterparse其中包含更快的版本lxml

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()
于 2013-03-29T09:26:54.630 回答
1

感谢您的支持,我终于编写了我的代码,它在这里工作得很好

import lxml import etree    
for event, element in etree.iterparse(the_xml_file):
    if 'TV' in element.tag:
        print element.text
于 2013-04-08T15:51:09.987 回答