Seite 1 von 1

ElementTree: XML parsen

Verfasst: Samstag 23. Dezember 2006, 18:12
von blan
hallo, ich wollt mir ein kleinen XML parser für meine daten basteln und hab mich für ElementTree entschieden weils leichter scheint als die anderen. Ich hab folgende Struktur

Code: Alles auswählen

<content>
  <genre type="audio">
    <index name="Hip-Hop">
      <artist>
        <name>artist</name>
      </artist>

      <artist>
        <name>artist</name>
      </artist>
    </index>

    <index name="Rock">
    </index>

    <index name="Punk">
    </index>
  </genre>

  <genre type="video">
    <index name="Action">
    </index>
  </genre>
</content>
ich hab schon ein bischen rumprobiert aber komm nicht zu 100% dahinter, gibt es denn eine gute Reference oder so zu ElementTree.

kann mir jemand ein Beispiel zeigen, wie ich das ambesten parse?

danke!

mfg blan[/code]

Verfasst: Samstag 23. Dezember 2006, 19:27
von BlackJack
Wenn Du das XML an `ElementTree` übergeben hast, dann ist das Parsen doch schon erledigt. Du bekommst einen Baum aus `Element`-Objekten zurück, die Du traversieren kannst. Der Wurzelknoten enthält zum Beispiel die beiden `genre`-Elemente. Mit `find()` bzw. `findall()` kannst man eine -- leider ziemlich kleine -- Untermenge von XPath benutzen um Knoten im Baum zu finden.

Code: Alles auswählen

In [44]: doc = etree.fromstring(source)

In [45]: for node in doc:
   ....:     print node.tag, node.get('type')
   ....:
genre audio
genre video

In [46]: doc.getchildren()
Out[46]: [<Element genre at -4870cd34>, <Element genre at -4870c9d4>]

In [47]: for node in doc.findall('.//index'):
   ....:     print node.tag, node.get('name')
   ....:
index Hip-Hop
index Rock
index Punk
index Action

Verfasst: Sonntag 24. Dezember 2006, 11:34
von blan
BlackJack hat geschrieben:Wenn Du das XML an `ElementTree` übergeben hast, dann ist das Parsen doch schon erledigt. Du bekommst einen Baum aus `Element`-Objekten zurück, die Du traversieren kannst. Der Wurzelknoten enthält zum Beispiel die beiden `genre`-Elemente. Mit `find()` bzw. `findall()` kannst man eine -- leider ziemlich kleine -- Untermenge von XPath benutzen um Knoten im Baum zu finden.

Code: Alles auswählen

In [44]: doc = etree.fromstring(source)

In [45]: for node in doc:
   ....:     print node.tag, node.get('type')
   ....:
genre audio
genre video

In [46]: doc.getchildren()
Out[46]: [<Element genre at -4870cd34>, <Element genre at -4870c9d4>]

In [47]: for node in doc.findall('.//index'):
   ....:     print node.tag, node.get('name')
   ....:
index Hip-Hop
index Rock
index Punk
index Action
okay danke, soweit kann ich noch folgen - aber ich versteh das mit dem SubElement nicht ganz.. wenn ich versuch bei "<artist>" mit SubElement die Elemente rauszubekommen gibt er immer 0 aus, aber "<name>" is doch ein SubElement von "<artist>" ?

Code: Alles auswählen

>>> import elementtree.ElementTree as et
>>> import cElementTree as et
>>> 
>>> tree = et.parse("test.xml")
>>> root = tree.getroot()
>>> 
>>> et.SubElement(root, "genre")
<Element 'genre' at 0xb7d2d8d8>
>>> a = et.SubElement(root, "genre")
>>> a.text
>>> b = et.SubElement(a, "index", name="Hip-Hop")
>>> et.SubElement(a, "index", name="Hip-Hop")
<Element 'index' at 0xb7d2d878>
>>> et.SubElement(b, "artist")
<Element 'artist' at 0xb7d2da40>
>>> c = et.SubElement(b, "artist")
>>> len(c)
0
>>> d = c.getchildren()
>>> d
[]
>>> 
mfg blan

Verfasst: Sonntag 24. Dezember 2006, 12:12
von BlackJack
blan hat geschrieben:okay danke, soweit kann ich noch folgen - aber ich versteh das mit dem SubElement nicht ganz.. wenn ich versuch bei "<artist>" mit SubElement die Elemente rauszubekommen gibt er immer 0 aus, aber "<name>" is doch ein SubElement von "<artist>" ?
`SubElement()` *erzeugt* neue Elemente. Da Du kein '<artist>' anlegst, kann auch keins da sein.

Code: Alles auswählen

In [4]: doc = etree.fromstring('<root />')

In [5]: a = etree.SubElement(doc, 'viking', name='eric')

In [6]: etree.dump(doc)
<root><viking name="eric" /></root>

In [7]: a
Out[7]: <Element viking at -486b9554>

Verfasst: Sonntag 24. Dezember 2006, 12:21
von blan
okay, deswegen also :)

und es gibt keine methode mitder ich ein subelement einfach via tag abfragen kann? denn ansonsten brauch ja voll viele ifs und fors..

mfg blan

Verfasst: Sonntag 24. Dezember 2006, 13:25
von XT@ngel
Ja, du könntest findall und find benutzen, wobei so wies aussieht ist Xpath nicht vollständig vorhanden? :roll:

Verfasst: Dienstag 26. Dezember 2006, 21:09
von Leonidas
XT@ngel hat geschrieben:wies aussieht ist Xpath nicht vollständig vorhanden? :roll:
Ich denke, dass lxml mehr XPath versteht, man kann es sicherlich mal versuchen, wenn man XPath braucht.