Seite 1 von 1

DOM - Anzahl Elemente ermitteln

Verfasst: Dienstag 2. Mai 2006, 13:14
von MissUnderstud
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.

Verfasst: Dienstag 2. Mai 2006, 14:27
von Joghurt

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.

Re: DOM - Anzahl Elemente ermitteln

Verfasst: Dienstag 2. Mai 2006, 14:31
von Leonidas
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))

Danke

Verfasst: Donnerstag 4. Mai 2006, 08:48
von Gynix
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

Verfasst: Donnerstag 4. Mai 2006, 15:11
von Leonidas
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.

Verfasst: Freitag 5. Mai 2006, 07:13
von 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:

Verfasst: Freitag 5. Mai 2006, 12:38
von Leonidas
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 :)