DOM - Anzahl Elemente ermitteln

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.
Antworten
MissUnderstud
User
Beiträge: 3
Registriert: Dienstag 2. Mai 2006, 13:04

Hallo,

ich möchte gerne mit DOM die Anzahl von Elementen ermitteln. Mein XML sieht etwa so aus:

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
<ADRESSE>
<Datensatz>
<Nachname>Schwarz</Nachname>
<Vorname>Sabine</Vorname>
<Strasse>Blauweg 4</Strasse>
<PLZ>53000</PLZ>
<Ort>Bonn</Ort>
</Datensatz>
<Datensatz>
<Nachname>Schwarz</Nachname>
<Vorname>Sabine</Vorname>
<Strasse>Blauweg 4</Strasse>
<PLZ>53000</PLZ>
<Ort>Bonn</Ort>
</Datensatz>
<Datensatz>
<Nachname>Schwarz</Nachname>
<Vorname>Sabine</Vorname>
<Strasse>Blauweg 4</Strasse>
<PLZ>53000</PLZ>
<Ort>Bonn</Ort>
</Datensatz>
</ADRESSE>
Das DOM-Progamm sieht so aus:

Code: Alles auswählen

import xml.dom.minidom
doc = xml.dom.minidom.parse('adressen.xml')
Elementknoten = doc.documentElement
anz_Knoten = Elementknoten.childNodes.length
anz_Tags = Elementknoten.childNodes[1].childNodes.length
print "Anz Knoten: %s, Anz Tags: %s" %(anz_Knoten, anz_Tags)
Wenn ich das DOM-Programm starte, erhalte ich folgende Ausgabe: Anz Knoten: 7, Anz Tags: 11
Das stimmt doch hinten und vorne nicht!!?
Ich erwarte eigentlich 3 Knoten und 5 Tags
Wer kann mir da weiterhelfen?

Gruß und Dank
- Gynix -

Edit (Leonidas): XML-Code in Tags gesetzt.
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Code: Alles auswählen

>>>doc.documentElement.childNodes
[<DOM Text node "\n">, <DOM Element: Datensatz at 0xa7a1f6cc>, <DOM Text node "\n">, <DOM Element: Datensatz at 0xa7a1fb0c>, <DOM Text node "\n">, <DOM Element: Datensatz at 0xa7a1fe0c>, <DOM Text node "\n">]
Die newlines werden als Text interpretiert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

MissUnderstud hat geschrieben:Wenn ich das DOM-Programm starte, erhalte ich folgende Ausgabe: Anz Knoten: 7, Anz Tags: 11
Das stimmt doch hinten und vorne nicht!!?
Ich erwarte eigentlich 3 Knoten und 5 Tags
Das stimmt hinten und vorne, wenn man sich überlegt, wie die DOM-Struktur aussieht.

So kommt das richtige raus:

Code: Alles auswählen

#!/usr/bin/env python
# -*- encoding: latin-1 -*-

import xml.dom.minidom

doc = xml.dom.minidom.parse('adressen.xml')

docroot = doc.documentElement
# DOM-Structure with all elements:
print docroot.childNodes

tagnodes = [node for node in docroot.childNodes if node.nodeName != '#text']

firstnode = tagnodes[0]
downnodes = [node for node in firstnode.childNodes if node.nodeName != '#text']

print "Nodes: %s, Tags: %s" % (len(tagnodes), len(downnodes))
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Gynix
User
Beiträge: 1
Registriert: Dienstag 2. Mai 2006, 12:48

Danke an euch beide; diesen Punkt hatte ich nicht beachtet. Das heisst doch dann, dass man die Zeilenumbrüche im XML-Dokument immer auf diese Art und Weise abfangen muss, da doch jeder XML-Editor beim Einrücken der Syntax autom. Zeilenumbrüche erzeugt!? Ich habe mal aus der adressen.xml alle Umbrüche und Einrückungen entfernt - und sieht da, es ging. Leider leidet dann natürlich die Lesbarbkeit des Dokuments erhebeblich!

Gruß Gynix
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Deswegen kannst du, wie ich es gezeigt habe, die Text-Elemente rauswerfen. Gegebenfalls kannst du das in eine hübsche Funktion packen, die nutzlose Textelemente rausfiltert und einen "bereinigten" DOM-Ast zurückgibt.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

Mit dem ElementTree Modul (wird ab Python 2.5 Bestandteil der Standardbibliothek) ist das recht einfach zu lösen:

Code: Alles auswählen

import elementtree.ElementTree as etree

adressen = """\
<?xml version="1.0" encoding="UTF-8"?> 
<ADRESSE>
    <Datensatz> 
        <Nachname>Schwarz</Nachname> 
        <Vorname>Sabine</Vorname> 
        <Strasse>Blauweg 4</Strasse> 
        <PLZ>53000</PLZ> 
        <Ort>Bonn</Ort> 
    </Datensatz> 
    <Datensatz> 
        <Nachname>Schwarz</Nachname> 
        <Vorname>Sabine</Vorname> 
        <Strasse>Blauweg 4</Strasse> 
        <PLZ>53000</PLZ> 
        <Ort>Bonn</Ort> 
    </Datensatz> 
    <Datensatz> 
        <Nachname>Schwarz</Nachname> 
        <Vorname>Sabine</Vorname> 
        <Strasse>Blauweg 4</Strasse> 
        <PLZ>53000</PLZ> 
        <Ort>Bonn</Ort> 
    </Datensatz> 
</ADRESSE>
"""

document = etree.fromstring(adressen)
print len(document)
print len(document[0])
DOM steht doch für "Doofes Objekt Modell", oder? :twisted:
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

BlackJack hat geschrieben:Mit dem ElementTree Modul (wird ab Python 2.5 Bestandteil der Standardbibliothek)
Soweit ich hier rausgelesen habe, wird nur der Core aufgenommen. Das ist aber auch schon ein Fortschritt, denke ich mal. Endlich kommt wieder mal ein pythonisches Modul in die Stdlib, nachdem logging zwar toll ist aber überfressen, optparse auch nicht ganz ohne ist und xml.dom einfach ein Java-Ripoff ist, der zwar praktisch ist, wenn man von JavaScript oder Java kommt, aber allzu angenehm kann man damit IMHO nicht arbeiten.

Ich werfe jetzt noch lxml in die Runde, welches auch eine ElementTree-artige API hat :)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten