2016-05-07 6 views
1

Ich analysiere eine XML-ähnliche Datei über Elementbaum in Python und und schreibe den Inhalt in einen Pandas-Datenrahmen.Überprüfen und entfernen Sie doppelte Kinder-Tags in XML

Ich bin derzeit mit dem folgenden Problem konfrontiert: Die Existenz von Kindern Tags wird Variante für verschiedene Tags sein. Dies wäre bei der erwähnten Lösung here kein Problem. Der komplizierte Teil besteht jedoch darin, dass einige Tags Child-Tags dupliziert haben, während andere dies nicht tun. Zum Beispiel hat die erste Produktbezeichnung zwei (verschiedene) Artikelnummern und zwei gleiche Produkttypen (doppelt), während die zweite nur jeweils eine hat.

<main> 
    <product> 
     <article_nr>B00024J7C6</article_nr> 
     <article_nr>44253</article_nr> 
     <product_type>x</product_type> 
     <product_type>x</product_type> 
    </product> 

    <product> 
     <article_nr>B00024J7C7</article_nr> 
     <product_type>y</product_type> 
    </product> 
</main> 

Was ich möchte, ist tun: 1.) entfernen Sie die Duplikate für ‚product_type‘ und 2.) den Wert NULL gesetzt, wenn kein zweites article_nr existiert, sonst den Wert nehmen .

Mein Code so weit:

def create_dataframe(data): 
    df = pd.DataFrame(columns=('article_nr', 'article_nr2', 'product_type', 'product_type2','product_type2')) 
    for i in range(len(data)): 
     obj = data.getchildren()[i].getchildren() 
     row = dict(itertools.izip(['article_nr', 'article_nr2', 'product_type', 'product_type2','product_type2'], 
         [obj[0].text, obj[1].text, obj[2].text, obj[3].text, obj[4].text])) 
     row_s = pd.Series(row) 
     row_s.name = i 
     df = df.append(row_s) 
    return df 

Dies funktioniert gut mit dem ersten Beispiel, aber offensichtlich nicht mit dem zweiten, weil es keine Werte für die zweite ‚article_nr‘ und ‚product_type‘ sind.

Ausgang sollte sein:

article_nr article_nr product_type 
B00024J7C6 44253   x 
B00024J7C7 NULL   y 
+0

Könnten Sie bitte hinzufügen, welchen Code Sie bisher und die gewünschte Ausgabe haben? Vielen Dank. – alecxe

+0

Warum können Sie das nicht nach dem Parsen tun? Warum musst du es vorher tun? – e4c5

+0

Ich habe den Code und die gewünschte Ausgabe hinzugefügt @alecxe – lomaga

Antwort

2

Blick auf Python remove duplicate elements from xml tree, vielleicht kann es Ihnen helfen. Some Thing wie folgt:

import xml.etree.ElementTree as ET 
path = 'in.xml' 
tree = ET.parse(path) 
root = tree.getroot() 
prev = None 

def elements_equal(e1, e2): 
    if type(e1) != type(e2): 
     return False 
    if e1.tag != e1.tag: return False 
    if e1.text != e2.text: return False 
    if e1.tail != e2.tail: return False 
    if e1.attrib != e2.attrib: return False 
    if len(e1) != len(e2): return False 
    return all([elements_equal(c1, c2) for c1, c2 in zip(e1, e2)]) 

for page in root:      # iterate over pages 
    elems_to_remove = [] 
    for elem in page: 
     if elements_equal(elem, prev): 
      print("found duplicate: %s" % elem.text) # equal function works well 
      elems_to_remove.append(elem) 
      continue 
     prev = elem 
    for elem_to_remove in elems_to_remove: 
     page.remove(elem_to_remove) 
tree.write("out.xml") 
+1

Der Code löste das erste Problem, indem alle Duplikate entfernt wurden. Ich löste das zweite von mir mit dem folgenden Code: 'für das Produkt in root.findall ('Produkt'): article_nr = product.findall ('article_nr') if len (article_nr) == 1: Produkt .insert (1, ET.Element ('article_nr')) ' – lomaga