2016-06-20 8 views
1

Ich habe eine XML, die Attribute für jeden Tag wie die folgende auf hat:Konvertieren von XML mit Werten auf Tags Zum Wörterbuch

<?xml version= "1.0" encoding="ISO-8859-1" ?> 
<month xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="my.xsd"> 
    <day Day="2016-1-01"> 
     <hour Hour="00:00"> 
      <Variables> 
       <a>211.3</a> 
       <b>78.94</b> 
       <c>0.6</c> 
      </Variables> 
     </hour> 
     <hour Hour="12:00"> 
      <Variables> 
       <a>155.5</a> 
       <b>85.5</b> 
       <c>0.42</c> 
      </Variables> 
     </hour> 
    </day> 
</month> 

Suche zu analysieren, um die XML und konvertieren Zum Wörterbuch, aber nicht mit den Tags, mit den Attributwerten.

Ich meine, wie der Lage sein, etwas zu machen, ähnlich wie:

>>> print d['2016-1-01']['12:00']['b'] 
>>> 85.5 

Die eigentliche XML viele Tage hat und auch Stunden. Ist das möglich?

Der einzige Weg, es zu analysieren, dass ich zu machen der Lage gewesen, das ist eine, aber schwierig, wenn Sie für mehrere verschiedene Variablen auf unterschiedlichen Zeiten aussehen wollen:

# Day 
for child_day in root: 
    print child_day.tag, child_day.attrib 

    # Hour 
    for child_hour in child_day: 
     print '\t', child_hour.tag, child_hour.attrib 

     # Variables 
     for child_Variables in child_hour: 
      print '\t\t', child_Variables.find('b').text 

Gibt es eine ähnliche Funktion wie this answer das macht dasselbe für Attributfall wie dieses anstelle der Umbauten?

Antwort

3

Die Antwort, die Sie verbanden, benutzt, was genannt wird, was dict comprehension genannt wird. Es ist eine ziemlich einfache und elegante Lösung, weil es auf jeder Ebene des ElementTree das gleiche tut, um das Niveau des dict zu erzeugen, so dass die Funktion sich selbst rekursiv nennen kann.

Aber wenn ich Sie richtig verstehe, werden Sie verschiedene Attribute jedes Tags greifen, abhängig davon, auf welcher Ebene Sie in der Struktur des ElementTree zu verwenden sind, wie die dict Schlüssel, und dann werden Sie es wechseln auf der untersten Ebene, um die Tag-Namen als Schlüssel und den Text als Werte zu verwenden. Ich konnte also keine Lösung finden, die so elegant ist wie die Antwort, die Sie in die Antwort eingefügt haben.

Wir können das dict-Verständnis auch nutzen, aber wir werden es ein paar Mal benutzen müssen (zumindest für die Lösung, die ich gefunden habe).

Es klingt wie Sie hoffen, eine dict zu erhalten, wie diese (bei Ihrer Probe XML) aussieht:

{ 
    "2016-1-01": { 
     "12:00": { 
      "a": "155.5", 
      "b": "85.5", 
      "c": "0.42", 
     }, 
     "00:00": { 
      "a": "211.3", 
      "b": "78.94", 
      "c": "0.6", 
     }, 
    }, 
} 

Um dies zu tun, werden Sie 3 Funktionen benötigen; 1, um die Erstellung jeder Ebene der dict (Tage, Stunden und Variablen) zu behandeln. Hier ist, wie sie aussehen:

def month_etree_to_dict(month): 
    d_list = month.getchildren() 
    d_dict = {d.attrib["Day"]: day_etree_to_dict(d) for d in d_list} 
    return d_dict 

def day_etree_to_dict(day): 
    h_list = day.getchildren() 
    h_dict = {h.attrib["Hour"]: hour_etree_to_dict(h) for h in h_list} 
    return h_dict 

def hour_etree_to_dict(hour): 
    v_list = hour.getchildren()[0].getchildren() 
    v_dict = {v.tag: v.text for v in v_list} 
    return v_dict 

Die Funktion month_etree_to_dict erzeugt eine dict wo die Schlüssel sind die Daten für jeden Tag. Die Werte sind Wörterbücher, die mit der Funktion day_etree_to_dict generiert werden. Die Funktion day_etree_to_dict macht das gleiche für jede Stunde, indem sie die Funktion hour_etree_to_dict aufruft. Die hour_etree_to_dict Funktion funktioniert etwas anders, indem eine zusätzliche Ebene springen nach unten in den ElementTree so kann es die <Variables>Element ‚s Kinder durchlaufen (<a>, <b> und <c>) als Schlüssel ihre Tag-Namen mit der dict und deren Text für die Werte.

Ich hoffe, das macht Sinn und ist nützlich für Sie.

+1

Einfach perfekt! Ich verstehe wirklich viel bessere Wörterbücher mit deiner Erklärung. Vielen Dank. – iblasi

+0

Kein Problem! Froh, dass ich helfen konnte! – SalmonMode

0

ich oft rekursiv defaultdict verwenden, wenn XML-Konvertierung dict wie so:

import xml.etree.ElementTree as ET 
from collections import defaultdict 


def Tree(): 
    return defaultdict(Tree) 

tree = ET.parse('x.xml') 
root = tree.getroot() 
d = Tree() 
for day in root.findall('day'): 
    for hour in day.findall('hour'): 
     for v in hour.findall('./Variables/*'): 
      d[day.attrib['Day']][hour.attrib['Hour']][v.tag] = v.text 

print d['2016-1-01']['12:00']['b'] 

Referenz:

Verwandte Themen