我正在尝试解析大型xml 文件并将标记打印到输出文件。我正在使用 minidom ,我的代码适用于30Mb文件,但对于较大的代码,它会出现内存错误。所以我使用bufferred读取文件,但现在我无法获得所需的输出。
> <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>
Sony,Burger,Apple
三星,比萨,HTC
Bravia,Pasta,BlackBerry
当用缓冲区阅读时,它给我一个输出说: - 索尼,汉堡,苹果 三星,的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(),但仍然无法获得所需的输出。
答案 0 :(得分:1)
您正在同时读取2048字节,这会将读取光标放在一行中间。在下一次阅读中,该行的其余部分将被丢弃,因为它不以标记开头。
不要滚动自己的解析器,而应考虑使用iterparse
。 lxml
中包含更快版本的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()
答案 1 :(得分:1)
感谢您的支持,我终于编写了我的代码,并且在这里工作得非常好
import lxml import etree
for event, element in etree.iterparse(the_xml_file):
if 'TV' in element.tag:
print element.text