我剛開始着眼於使用python從csv生成XML。我正在嘗試使用ElementTree來做到這一點。但是,我無法得到我想要的格式。使用Elementtree編寫Python大型XML代碼
Here是我使用的示例csv數據。原始數據大約有1200萬行,由此產生的全部xml大約有3800萬行。以下是我的代碼。
import csv
import sys
from xml.etree.ElementTree import Element, SubElement, Comment, ElementTree, tostring
from xml.etree import ElementTree
from xml.dom import minidom
def prettify(elem):
rough_string = tostring(elem, 'utf-8', method="xml")
reparsed = minidom.parseString(rough_string)
return reparsed.toprettyxml(indent=" ")
root = Element('plans')
sys.stdout = open('C:/Users/s/Desktop/xml6.xml', 'w')
print(prettify(root))
with open('C:/Users/s/Desktop/trip2.csv', 'rt') as f:
current_group = None
reader = csv.reader(f)
for row in reader:
personid, hno, pno, OXutmmtr, OYutmmtr, DXutmmtr, DYutmmtr, opcl, dpcl, depday, deptm, arrtm, newendacttma, dept, arr, newendacttmh, mode2, opurp2, dpurp2, dorp2 = row
if current_group is None or personid != old1 :
# Start a new group
current_group = SubElement(root, 'person', {'id':personid})
old1 = personid
pln = SubElement(current_group, 'plan')
activ = SubElement(pln, 'act', {'type':opurp2, 'x':OXutmmtr, 'y':OYutmmtr,})
trvl = SubElement(pln, 'leg', {'mode': mode2,})
activ = SubElement(pln, 'act',{'type': dpurp2, 'x': DXutmmtr, 'y': DYutmmtr,})
elif personid == old1:
trvl = SubElement(pln, 'leg', {'mode': mode2,})
activ = SubElement(pln, 'act', {'type': dpurp2, 'x': DXutmmtr,'y': DYutmmtr,})
if newendacttmh == "02:59:00":
sys.stdout = open('C:/Users/s/Desktop/xml6.xml', 'a')
print(prettify(current_group))
root.clear()
我需要一個像
<?xml version="1.0" ?>
<plans>
<person id="101">
<plan>
<act type="home" x="338471.624256" y="3114225.84531"/>
<leg mode="sov"/>
<act type="work" x="353108.46905" y="3086263.42028"/>
<leg mode="sov"/>
<act type="home" x="338471.624256" y="3114225.84531"/>
</plan>
</person>
<person id="201">
<plan>
<act type="home" x="338535.623855" y="3114558.14898"/>
<leg mode="hov3+"/>
<act type="meal" x="338520.432083" y="3105225.60283"/>
<leg mode="hov3+"/>
<act type="shop" x="333193.19769" y="3103842.61842"/>
<leg mode="hov3+"/>
<act type="pers.bus" x="338148.26292" y="3083556.85073"/>
<leg mode="hov3+"/>
<act type="home" x="338535.623855" y="3114558.14898"/>
</plan>
</person>
</plans>
的格式,但我得到的格式一樣
<?xml version="1.0" ?>
<plans/>
<?xml version="1.0" ?>
<person id="101">
<plan>
<act type="home" x="338471.624256" y="3114225.84531"/>
<leg mode="sov"/>
<act type="work" x="353108.46905" y="3086263.42028"/>
<leg mode="sov"/>
<act type="home" x="338471.624256" y="3114225.84531"/>
</plan>
</person>
<?xml version="1.0" ?>
<person id="201">
<plan>
<act type="home" x="338535.623855" y="3114558.14898"/>
<leg mode="hov3+"/>
<act type="meal" x="338520.432083" y="3105225.60283"/>
<leg mode="hov3+"/>
<act type="shop" x="333193.19769" y="3103842.61842"/>
<leg mode="hov3+"/>
<act type="pers.bus" x="338148.26292" y="3083556.85073"/>
<leg mode="hov3+"/>
<act type="home" x="338535.623855" y="3114558.14898"/>
</plan>
</person>
從本質上講,我想,當我到了每個人的結束追加到文件記錄(由時間字符串02:59:00表示),因爲如果我等到整個根樹被構造,那麼我正在運行內存錯誤問題。有趣的是,內存使用永遠不會超過2 GB,即使仍然存在12 GB的內存,程序仍會出現內存錯誤問題。我試圖遵循關於使用ElementTree(top).write(sys.stdout)
序列化XML流的建議here,但我無法操作它。我知道(某種)SAX解析器更適合大型XML創建。但是,我現在有點害怕。任何建議或建議將對我有用。
我沒有看到您的兩個XML示例之間的任何區別。你只是在談論空白區別? – BrenBarn
在第一個(也是正確的)版本中,所有'person'元素都在'plans'元素中。在第二個版本中,'plans'元素在第二行開始和結束,'person'元素獨立於'plans'。此外,在第二版xml序言中,<?xml version =「1.0」?>'重複每個'person'元素。 – Gandalf
你爲什麼用奇怪的方式做事,用'tostring'輸出XML,然後用minidom再讀一遍? – BrenBarn