ElementTree: XML parsen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
blan
User
Beiträge: 23
Registriert: Donnerstag 4. Mai 2006, 17:30

ElementTree: XML parsen

Beitragvon blan » Samstag 23. Dezember 2006, 18:12

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]
BlackJack

Beitragvon BlackJack » Samstag 23. Dezember 2006, 19:27

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
blan
User
Beiträge: 23
Registriert: Donnerstag 4. Mai 2006, 17:30

Beitragvon blan » Sonntag 24. Dezember 2006, 11:34

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
BlackJack

Beitragvon BlackJack » Sonntag 24. Dezember 2006, 12:12

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>
blan
User
Beiträge: 23
Registriert: Donnerstag 4. Mai 2006, 17:30

Beitragvon blan » Sonntag 24. Dezember 2006, 12:21

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
XT@ngel
User
Beiträge: 256
Registriert: Dienstag 6. August 2002, 14:36
Kontaktdaten:

Beitragvon XT@ngel » Sonntag 24. Dezember 2006, 13:25

Ja, du könntest findall und find benutzen, wobei so wies aussieht ist Xpath nicht vollständig vorhanden? :roll:
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 26. Dezember 2006, 21:09

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.
My god, it's full of CARs! | Leonidasvoice vs Modvoice

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder