14. Dokumentenverarbeitung XML
![]() |
Betrachten wir das folgende Dokument XML:
<tribu>
<enseignant>
<personne sexe="M">
<nom>dupont</nom>
<prenom>jean</prenom>
<age>28</age>
ceci est un commentaire
</personne>
<section>27</section>
</enseignant>
<etudiant>
<personne sexe="F">
<nom>martin</nom>
<prenom>charline</prenom>
<age>22</age>
</personne>
<formation>dess IAIE</formation>
</etudiant>
</tribu>
Wir analysieren dieses Dokument, um die folgende Konsolenausgabe zu erzeugen:
tribu
enseignant
(personne,(sexe,M) )
nom
[dupont]
/nom
prenom
[jean]
/prenom
age
[28]
/age
/personne
section
[27]
/section
/enseignant
etudiant
(personne,(sexe,F) )
nom
[martin]
/nom
prenom
[charline]
/prenom
age
[22]
/age
/personne
formation
[dess IAIE]
/formation
/etudiant
/tribu
Wir müssen wissen, wie man Folgendes erkennt:
- ein Start-Tag wie <formation>;
- ein End-Tag wie </Lehrer>;
- ein Start-Tag mit Attributen wie <person sex="F">;
- den Inhalt eines Tags wie martin in <nom>martin</nom>.
Das Programm zur Analyse eines Codes wie XML wird als Parser XML bezeichnet. Zwei Module stellen uns die Funktionen zur Analyse eines Codes XML zur Verfügung: xml.sax und xml.sax.handler.
Das Modul [xml.sax] stellt uns über die Anweisung einen Parser XML zur Verfügung:
Dieser Parser analysiert den Text XML sequenziell. Er ruft bei bestimmten Ereignissen vom Benutzer definierte Methoden auf:
- die Methode startElement bei einem Tag-Anfang;
- die Methode endElement bei einem Tag-Ende;
- die Methode characters beim Hauptteil eines Tags.
Wir müssen dem Parser die Klasse angeben, die diese Methoden implementiert:
Wir übergeben an die Methode setContentHandler des Parsers eine Instanz der Klasse, die die Methoden startElement, endElement und characters implementiert. Die verwendete Klasse ist eine von der Klasse xml.sax.handler.ContentHandler abgeleitete Klasse. Die vorangegangenen Methoden werden mit folgenden Parametern aufgerufen:
- name ist der Name des Start-Tags. attributs ist das Attributwörterbuch des Tags. Für das Tag <person sexe="M"> erhalten wir also name="personne" und attributs={'sexe':'M'}
- name ist der Name des End-Tags. Für das Tag </etudiant> lautet der Name also name='etudiant'.
- „data“ ist der Inhalt des Tags. Wenn das Tag also
lautet, ergibt sich „data='\r\n dupont\r\n '“. In der Regel werden die Leerzeichen vor und nach den Daten entfernt.
Nachdem dies geklärt ist, können wir zum Skript zur Analyse eines XML-Dokuments übergehen:
# -*- coding=utf-8 -*-
import xml.sax, xml.sax.handler,re
# Verwaltungsklasse XML
class XmlHandler(xml.sax.handler.ContentHandler):
# Funktion, die beim Auftreten eines Start-Tags aufgerufen wird
def startElement(self,name,attributs):
global depth
# eine Folge von Leerzeichen (Einrückung)
print " " * depth,
# Attribute
precisions=""
for (attrib,valeur) in attributs.items():
precisions+="(%s,%s) " % (attrib,valeur)
# Der Name des Tags und eventuelle Attribute werden angezeigt
if precisions :
print "(%s,%s)" % (name,precisions)
else :
print name
# eine weitere Ebene in der Baumstruktur
depth+=1
# Handelt es sich um ein Daten-Tag?
global balisesDonnees,baliseDeDonnees
if balisesDonnees.has_key(name.lower()):
baliseDeDonnees=1
# Die Funktion, die beim Auftreten eines End-Tags aufgerufen wird
def endElement(self,name):
# Tag-Ende
# Einrückungsebene
global depth
depth-=1
# eine Folge von Leerzeichen (Einrückung)
print " " * depth,
# der Name des Tags
print "/%s" % (name)
# die Funktion zur Anzeige der Daten
def characters(self,data):
# Daten
global baliseDeDonnees
# Ist das aktuelle Tag ein Datentag?
if not baliseDeDonnees :
return
# Einrückungstiefe
global depth
# eine Folge von Leerzeichen (Einrückung)
print " " * depth,
# Die Daten werden angezeigt
match=re.match(r"^\s*(.*)\s*$",data)
if match:
print "[%s]" % (match.groups()[0])
# Ende des Daten-Tags
baliseDeDonnees=False
# ------------------------------------------- main
# das Programm
# Daten
file="data.xml" # die XML-Datei
depth=0 # Einarbeitungstiefe = Tiefe in der Baumstruktur
balisesDonnees={"nom":1,"prenom":1,"age":1,"section":1,"formation":1}
baliseDeDonnees=True # Wenn „true“, gibt dies an, dass es sich um ein Daten-Tag handelt
# Es wird ein Objekt zur XML-Textanalyse erstellt
xml_parser=xml.sax.make_parser()
# der Tag-Manager
xml_parser.setContentHandler(XmlHandler())
# Auswertung der XML-Datei
xml_parser.parse(file)
Hinweise:
- Das Skript nutzt die Funktionsbibliothek der Module xml.sax und xml.sax.handler (Zeile 3);
- Zeile 62: die analysierte Datei XML;
- Zeile 68: der Parser XML;
- Zeile 70: Der Handler für die vom Parser ausgelösten Ereignisse ist eine Instanz der Klasse XmlHandler;
- Zeile 72: Die Analyse des Dokuments XML wird gestartet;
- Zeile 6: Die Klasse, die die Methoden startElement, endElement und characters implementiert. Sie ist von der Klasse xml.sax.handler.ContentHandler abgeleitet, die vom Parser verwendete Methoden implementiert;
- Zeile 9: die Methode startElement;
- Zeile 30: die Methode endElement;
- Zeile 41: die Methode characters.
Die Ergebnisse entsprechen denen, die zu Beginn dieses Absatzes vorgestellt wurden.
