次の点についてご協力をお願いいたします: 大きな XML ファイルを読み取って CSV に変換する必要があります。
同じことを行うと思われる2つの関数があります.1つ(function1)はiterparseを使用し(約2GBのファイルを処理する必要があるため)、もう1つは使用しません(function2)。
Function2 は、同じ XML ファイル (ただし、最大 150 MB) に対して非常にうまく機能し、そのサイズを超えると、メモリが原因で失敗します。
私が抱えている問題は、(関数 1 の) コードがエラーを出さないという事実にもかかわらず、子の一部が失われることです (これは大きな問題です!)。一方、 Function2 はすべての子を読み取り、「緩む」ことも失敗することもありません。
Q: function1 のコードで、一部の子が失われる (または正しく読み取れない、または無視される) 理由を確認できますか?
注 1: 必要な場合に備えて、50 KB の XML サンプルを送信する準備ができています。
注 2: 変数 'nchil_count' は、子の数をカウントするためのものです。
コード (関数 1):
def function1 ():
# This function uses Iterparse
# Doesn't give errors but looses some children. Why?
# prints output to csv file, WCEL.csv
from xml.etree.cElementTree import iterparse
fname = "C:\Leonardo\Input data\Xml input data\NetactFiles\Netact_3g_rnc11_t1.xml"
# ELEMENT_LIST = ["WCEL"]
# Delete contents from exit file
open("C:\Leonardo\Input data\Xml input data\WCEL.csv", 'w').close()
# Open exit file
with open("C:\Leonardo\Input data\Xml input data\WCEL.csv", "a") as exit_file:
with open(fname) as xml_doc:
context = iterparse(xml_doc, events=("start", "end"))
context = iter(context)
event, root = context.next()
for event, elem in context:
if event == "start" and elem.tag == "{raml20.xsd}managedObject":
# if event == "start":
if elem.get('class') == 'WCEL':
print elem.attrib
# print elem.tag
element = elem.getchildren()
nchil_count = 0
for child in element:
if child.tag == "{raml20.xsd}p":
nchil_count = nchil_count + 1
# print child.tag
# print child.attrib
val = child.text
# print val
val = str (val)
exit_file.write(val + ",")
exit_file.write('\n')
print nchil_count
elif event == "end" and elem.tag == "{raml20.xsd}managedObject":
# Clear Memory
root.clear()
xml_doc.close()
exit_file.close()
return ()
コード (関数 2):
def function2 (xmlFile):
# Using Element Tree
# Successful
# Works well with files of 150 MB, like an XML (RAML) RNC export from Netact (1 RNC only)
# It fails with huge files due to Memory
import xml.etree.cElementTree as etree
import shutil
with open("C:\Leonardo\Input data\Xml input data\WCEL.csv", "a") as exit_file:
# Populate the values per cell:
tree = etree.parse(xmlFile)
for value in tree.getiterator(tag='{raml20.xsd}managedObject'):
if value.get('class') == 'WCEL':
print value.attrib
element = value.getchildren()
nchil_count = 0
for child in element:
if child.tag == "{raml20.xsd}p":
nchil_count = nchil_count + 1
# print child.tag
# print child.attrib
val = child.text
# print val
val = str (val)
exit_file.write(val + ",")
exit_file.write('\n')
print nchil_count
exit_file.close() ## File closing after writing.
return ()