2016-04-03 134 views
0

我有一個具有數據列表的長XML文件列表。基於「ID」,我想從文件中刪除一些節點。如果ID值重複且沒有元數據,那麼我想保留具有元數據的文件節點並刪除其他元數據。 如果相同的ID值看到兩次,都沒有元數據,然後保留第一個和刪除第二個。根據條件刪除XML文件中的重複條目。

Input.xml中

<?xml version="1.0"?> 
<Def check=""> 
-<ID Elm="Front Sonar" ID="Opt-0001"/> 

-<ID Elm="Rear Sonar" ID="Opt-0002"> 
<BlockID Wid="100" Auto="true"/> 
<Check Auto="true" Siz="20" Nam="Fonts"/> 
<Update Auto="true" Nam="Styles"/> 
-<Updates Auto="true"> 
<Update Name="Type_1"/> 
<Update Name="Type_21"/> 
</Updates> 
</ID> 
-<ID Elm="Sonar Settings" ID="Opt-0003"> 
<BlockID Wid="80" Auto="true"/> 
<Check Auto="true" Siz="2" Nam="Fun"/> 
<Update Auto="true" Nam="done"/> 
-<Updates Auto="true"> 
<Update Name="Type_31"/> 
<Update Name="Type_2"/> 
</Updates> 
</ID> 
-<ID Elm="Sonar" ID="Opt-0004"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="Menu" ID="ValOpt-0001"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="Cancel" ID="ValOpt-0002"/> 
-<ID Elm="Go Home" ID="ValOpt-0003"/> 
-<ID Elm="Group" ID="Opt-0001"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="School" ID="Opt-0002"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="Book" ID="Opt-0003"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="Lang" ID="ValOpt-0001"> 
<BlockID Wid="100" Auto="true"/> 
<Check Auto="true" Siz="20" Nam="Fonts"/> 
<Update Auto="true" Nam="Styles"/> 
-<Updates Auto="true"> 
<Update Name="Type_1"/> 
<Update Name="Type_21"/> 
</Updates> 
</ID> 
-<ID Elm="Back" ID="ValOpt-0002"> 
<BlockID Wid="80" Auto="true"/> 
<Check Auto="true" Siz="2" Nam="Fun"/> 
<Update Auto="true" Nam="done"/> 
-<Updates Auto="true"> 
<Update Name="Type_31"/> 
<Update Name="Type_2"/> 
</Updates> 
</ID> 
-<ID Elm="Exit" ID="ValOpt-0003"/> 
</Def> 

預期的Output.xml

<?xml version="1.0"?> 
<Def check=""> 
-<ID Elm="Front Sonar" ID="Opt-0001"/> 
-<ID Elm="Rear Sonar" ID="Opt-0002"> 
<BlockID Wid="100" Auto="true"/> 
<Check Auto="true" Siz="20" Nam="Fonts"/> 
<Update Auto="true" Nam="Styles"/> 
-<Updates Auto="true"> 
<Update Name="Type_1"/> 
<Update Name="Type_21"/> 
</Updates> 
</ID> 
-<ID Elm="Sonar Settings" ID="Opt-0003"> 
<BlockID Wid="80" Auto="true"/> 
<Check Auto="true" Siz="2" Nam="Fun"/> 
<Update Auto="true" Nam="done"/> 
-<Updates Auto="true"> 
<Update Name="Type_31"/> 
<Update Name="Type_2"/> 
</Updates> 
</ID> 
-<ID Elm="Sonar" ID="Opt-0004"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="Cancel" ID="ValOpt-0002"/> 
-<ID Elm="Go Home" ID="ValOpt-0003"/> 
-<ID Elm="Group" ID="Opt-0001"> 
<!-- no Elm reference found --> 
</ID> 
-<ID Elm="Lang" ID="ValOpt-0001"> 
<BlockID Wid="100" Auto="true"/> 
<Check Auto="true" Siz="20" Nam="Fonts"/> 
<Update Auto="true" Nam="Styles"/> 
-<Updates Auto="true"> 
<Update Name="Type_1"/> 
<Update Name="Type_21"/> 
</Updates> 
</ID> 
-<ID Elm="Back" ID="ValOpt-0002"> 
<BlockID Wid="80" Auto="true"/> 
<Check Auto="true" Siz="2" Nam="Fun"/> 
<Update Auto="true" Nam="done"/> 
-<Updates Auto="true"> 
<Update Name="Type_31"/> 
<Update Name="Type_2"/> 
</Updates> 
</ID> 
</Def> 

使用Element樹,我試圖檢查 如果從列表行starteswith 「」 #remove elemet。 else 打印「元素有元數據」
但不幸的是我的函數沒有進入循環本身....我總是在其他條件下獲得print語句。任何幫助有關這?

回答

0

期望的輸出仍然有一些重複。從下面的代碼的輸出與預期不同,但它實際上刪除所有重複:

from lxml import etree 

xml_input = 'Input.xml' 
xml_output = 'Output.xml' 

with open(xml_input) as xml: 
    root = etree.XML(xml.read()) 

#create dictionary where key is an ID and value is a list of nodes with the ID 
node_dict = {} 
for node in root.xpath('//*[@ID]'): 
    try: 
     node_dict[node.get('ID')].append(node) 
    except KeyError: 
     node_dict[node.get('ID')] = [node] 

for key, nodes in node_dict.iteritems(): 
    #find all nodes with childs 
    nodes_with_childs = [node for node in nodes if len(node.xpath('./*')) > 0] 

    #leave only first node with childs, remove other nodes 
    if len(nodes_with_childs) > 0: 
     for node in set(nodes) - set([nodes_with_childs[0]]): 
     node.getparent().remove(node) 
    else: 
     #leave only first node, remove other nodes 
     for node in nodes[1:]: 
     node.getparent().remove(node) 

with open(xml_output, 'w') as xml: 
    xml.write(etree.tostring(root, xml_declaration=True)) 
+0

它完美罰款...感謝ü... – HARPAL

+0

找到1個問題......在節點的一些文本的特殊字符。 ..應對XML文件可以看到一些特殊字符的垃圾值...這怎麼處理? – HARPAL

+0

我在我的Input.xml文件中有這樣的一行 「」 刪除重複條目並將內容複製到output.xml ,其數值變爲 HARPAL