2016-10-18 92 views
0

我擁有巨大的嵌套結構的XML。 贊一個如何使嵌套的xml結構與Python平坦

<root> 
<node1> 
    <subnode1> 
    <name1>text1</name1> 
    </subnode1> 
</node1> 
<node2> 
    <subnode2> 
    <name2>text2</name2> 
    </subnode2> 
</node2> 
</root> 

我想將它轉換爲

<root> 
    <node1> 
    <name1>text1</name1> 
    </node1> 
    <node2> 
    <name2>text2</name2> 
    </node2> 
</root> 

我用下面的步驟

from xml.etree import ElementTree as et 

tr = etree.parse(path) 
root = tr.getroot() 

for node in root.getchildren(): 
    for element in node.iter(): 
    if (element.text is not None): 
     node.extend(element) 

我也試圖與node.append(element),但它也不起作用嘗試把它添加元素最後,我得到了無限循環。 任何有助於表示讚賞。

回答

1

幾點要在這裏提到:

首先,你的測試element.text is not None總是返回True如果您解析XML文件上面使用xml.etree.Elementree,因爲在每一個節點的末尾給出,有一個新的行字符,因此,每個假定不具有文本節點中的文本總是具有\n個字符。另一種方法是使用lxml.etree.parse,其中lxml.etree.XMLParser忽略如下的空白文本。其次,在閱讀樹時追加到樹上是不好的。同樣的原因,爲什麼這個代碼將會給無限循環:

>>> a = [1,2,3,4] 
>>> for k in a: 
     a.append(5) 

你可以看到@Alex馬爾泰利的答案這個問題在這裏:Modifying list while iterating有關問題。

因此,您應該製作一個緩衝區 XML樹並相應地構建它,而不是在遍歷它時修改樹。

from xml.etree import ElementTree as et 
import pdb; 

from lxml import etree 

p = etree.XMLParser(remove_blank_text=True) 
path = 'test.xml' 
tr = et.parse(path, parser = p) 
root = tr.getroot() 

buffer = et.Element(root.tag); 

for node in root.getchildren(): 
    bnode = et.Element(node.tag) 
    for element in node.iter(): 
     #pdb.set_trace() 
     if (element.text is not None): 
      bnode.append(element) 
      #node.extend(element) 
    buffer.append(bnode) 

et.dump(buffer) 

採樣運行和結果:

Chip [email protected] 01:01:[email protected] ~: python stackoverflow.py 
<root><node1><name1>text1</name1></node1><node2><name2>text2</name2></node2></root> 

注意:您可以隨時嘗試打印在這裏蟒蛇以下教程使用lxml包一個漂亮的XML樹:Pretty printing XML in Python,因爲我打印出來的樹是相當可怕通過肉眼閱讀。

+0

這有幫助。非常感謝你! –