2016-04-03 4 views
0

Ich habe eine einzige Liste von langen XML-Datei mit einer Liste von Daten. Basierend auf "ID" möchte ich einige Knoten aus der Datei entfernen. Wenn der ID-Wert wiederholt wird und keine Metadaten enthält, möchte ich den Dateiknoten beibehalten, der Metadaten enthält, und andere entfernen. Wenn derselbe ID-Wert zweimal angezeigt wird und beide keine Metadaten haben, dann behalten Sie den ersten und entfernen Sie den zweiten.Entfernen Sie doppelte Einträge aus XML-Dateien, basierend auf der Bedingung.

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> 

erwartet 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> 

mit Element Baum, Ich habe versucht, für prüft wird, ob Linie starteswith "" #remove elemet aus der Liste. sonst print "Element hat Metadaten"
aber leider geht meine Funktion nicht in die Schleife selbst .... Ich bekomme immer print-Anweisung unter sonst Bedingung. Irgendwelche Hilfe diesbezüglich ????

Antwort

0

Die erwartete Ausgabe enthält immer noch einige Duplikate. Die Ausgabe von folgendem Code ist anders als erwartet, aber es tatsächlich entfernt alle Duplikate:

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

Es funktioniert völlig in Ordnung ... Thank u ... – HARPAL

+0

Gefunden 1 Problem ... Einige von Text in Knoten Sonderzeichen enthalten. .. Während der Verarbeitung von XML-Dateien kann ein wenig Wert für Sonderzeichen zu sehen sein ... Wie kann das gehandhabt werden ??? – HARPAL

+0

Ich habe eine Zeile so in meiner Input.xml-Datei "" Nach dem Entfernen von doppelten Einträgen und Kopieren des Inhalts in output.xml , sein Wert ändert sich in HARPAL

Verwandte Themen