簡體   English   中英

使用xmltree解析大型python xml

[英]Parse large python xml using xmltree

我有一個Python腳本,可以解析巨大的xml文件(最大的是446 MB)

    try:
        parser = etree.XMLParser(encoding='utf-8')
        tree = etree.parse(os.path.join(srcDir, fileName), parser)
        root = tree.getroot()
    except Exception, e:
        print "Error parsing file "+str(fileName) + " Reason "+str(e.message)

    for child in root:
        if "PersonName" in child.tag:
            personName = child.text

這是我的xml的樣子:

<?xml version="1.0" encoding="utf-8"?>
<MyRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" uuid="ertr" xmlns="http://www.example.org/yml/data/litsmlv2">
  <Aliases authority="OPP" xmlns="http://www.example.org/yml/data/commonv2">
     <Description>myData</Description>
     <Identifier>43hhjh87n4nm</Identifier>
  </Aliases>
  <RollNo uom="kPa">39979172.201167159</RollNo>
  <PersonName>Miracle Smith</PersonName>
  <Date>2017-06-02T01:10:32-05:00</Date>
....

我要做的就是獲取PersonName標簽的內容。 我不在乎的其他標簽。

不幸的是,我的文件很大,使用上面的代碼時,我總是收到此錯誤消息:

Error parsing file 2eb6d894-0775-e611.xml Reason unknown error, line 1, column 310915857
Error parsing file 2ecc18b5-ef41-e711-80f.xml Reason Extra content at the end of the document, line 1, column 3428182
Error parsing file 2f0d6926-b602-e711-80f4-005.xml Reason Extra content at the end of the document, line 1, column 6162118
Error parsing file 2f12636b-b2f5-e611-80f3-00.xml Reason Extra content at the end of the document, line 1, column 8014679
Error parsing file 2f14e35a-d22b-4504-8866-.xml Reason Extra content at the end of the document, line 1, column 8411238
Error parsing file 2f50c2eb-55c6-e611-80f0-005056a.xml Reason Extra content at the end of the document, line 1, column 7636614
Error parsing file 3a1a3806-b6af-e611-80ef-00505.xml Reason Extra content at the end of the document, line 1, column 11032486

我的XML非常好,沒有多余的內容。似乎大文件解析會導致錯誤。 我已經看過iterparse(),但是它要實現的目標似乎很復雜,因為它提供了整個DOM的解析,而我只希望位於根目錄下的一個標記。 另外,不是給我一個很好的示例以按標簽名稱獲取正確的值嗎?

我應該使用正則表達式解析還是grep / awk方式做到這一點? 或對我的代碼進行的任何調整都會使我在這些巨大的文件中獲得“人名”?

更新:嘗試過此示例,它似乎正在從xml打印整個世界,除了我的標簽?

是否iterparse從文件的底部讀取到頂部? 在那種情況下,到達頂部即我的PersonName標簽將花費很長時間。 我嘗試更改下面的行以讀取end to start events =(“ end”,“ start”),它做同樣的事情!!!

path = []
for event, elem in ET.iterparse('D:\\mystage\\2-80ea-005056.xml', events=("start", "end")):
    if event == 'start':
            path.append(elem.tag)
    elif event == 'end':
            # process the tag
            print elem.text  // prints whole world 
            if elem.tag == 'PersonName':
                print elem.text
            path.pop()

在這種情況下,Iterparse並不難使用。

temp.xml是您的問題中顯示的文件,最后以</MyRoot>為一行。

如果可以的話,可以將source =視為鍋爐庫,它將分析xml文件並逐元素返回該數據塊,指示該塊是元素的“開始”還是“結束”,並提供有關元素的信息。元件。

在這種情況下,我們只需要考慮“開始”事件。 我們注意“ PersonName”標簽並拾取其文本。 在xml文件中找到了唯一的一項后,我們放棄了處理。

>>> from xml.etree import ElementTree
>>> source = iter(ElementTree.iterparse('temp.xml', events=('start', 'end')))
>>> for an_event, an_element in source:
...     if an_event=='start' and an_element.tag.endswith('PersonName'):
...         an_element.text
...         break
... 
'Miracle Smith'

編輯,以回應評論中的問題:

通常,您不會這樣做,因為iterparse旨在用於大塊xml。 但是,通過將字符串包裝在StringIO對象中,可以使用iterparse處理iterparse

>>> from xml.etree import ElementTree
>>> from io import StringIO
>>> xml = StringIO('''\
... <?xml version="1.0" encoding="utf-8"?>
... <MyRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" uuid="ertr" xmlns="http://www.example.org/yml/data/litsmlv2">
...   <Aliases authority="OPP" xmlns="http://www.example.org/yml/data/commonv2">
...        <Description>myData</Description>
...             <Identifier>43hhjh87n4nm</Identifier>
...               </Aliases>
...                 <RollNo uom="kPa">39979172.201167159</RollNo>
...                   <PersonName>Miracle Smith</PersonName>
...                     <Date>2017-06-02T01:10:32-05:00</Date>
... </MyRoot>''')
>>> source = iter(ElementTree.iterparse(xml, events=('start', 'end')))
>>> for an_event, an_element in source:
...     if an_event=='start' and an_element.tag.endswith('PersonName'):
...         an_element.text
...         break
...     
'Miracle Smith'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM