XML::Simple

(Auszug aus "Perl & XML" von Erik T. Ray & Jason McIntosh)

Das einfachste Baummodell finden wir in Grant McLeans Modul XML::Simple. Es wurde zum Lesen und Schreiben einfacher XML-Dateien (zum Beispiel Konfigurationsdateien) entwickelt. Der Programmierer muß sich nicht mit XML und Parsern auskennen – das Dokument wird mit Hilfe von Arrays und Hashes repräsentiert, und mit denen sollte sich ein Perl-Programmierer auskennen.

Das folgende Beispiel zeigt eine einfache Konfigurationsdatei.

Beispiel: Konfigurationsdatei eines Programms

<konfiguration>
    <zeichensatz role="default">
        <name>Times New Roman</name>
        <groesse>14</groesse>
    </zeichensatz>
    <fenster>
        <hoehe>352</hoehe>
        <breite>417</breite>
        <position_x>100</position_x>
        <position_y>120</position_y>
    </fenster>
</konfiguration>

XML::Simple macht den Zugriff auf diese Daten bemerkenswert einfach. Das Beispiel unten zeigt, wie man die Zeichensatz-Informationen aus der Datei lesen kann.

Beispiel: Ein Programm zum Lesen von Zeichensatzinformationen

use XML::Simple;

my $simple = XML::Simple->new(); # Initialisierung des Objekts
my $tree = $simple->XMLin( './data.xml' ); # Lies das Dokument und speichere es in $tree

# Zugriff auf die Daten in $tree
print "Der Anwender wünscht den Zeichensatz " . $tree->{ zeichensatz }->{ name } .
     " mit einer Größe von " . $tree->{ zeichensatz }->{ groesse } . " Punkten.\n";

Wir initialisieren zunächst ein Objekt der Klasse XML::Simple. Dann lassen wir den Parser arbeiten, indem wir seine Methode

XMLin( ) aufrufen. Die Methode liefert als Ergebnis eine Referenz auf das Wurzelelement des Baums. Dieser Baum besteht aus einer hierarchisch angeordneten Menge von Hashreferenzen. Die Schlüssel dieser Hashes sind die Elementnamen. Die Werte sind entweder Strings oder Referenzen auf andere Hashes mit den Daten eines Kindelements. Damit haben wir einen sehr klaren und einfachen Weg, auf bestimmte Stellen des Dokuments zuzugreifen.

Um die Idee zu illustrieren, lassen wir uns am besten die Baumstruktur mit Data::Dumper ausgeben. Dabei handelt es sich um ein Modul, das Datenstrukturen in Perl-Quelltext umwandelt und dadurch visualisiert. Zu diesem Zweck ergänzen wir das Programm um die beiden folgenden Zeilen:

use Data::Dumper;
print Dumper( $tree );

Wir erhalten damit die folgende Ausgabe:

$tree = {         
         'zeichensatz' => {
                  'groesse' => '14',
                  'name' => 'Times New Roman',
                  'role' => 'default'
               },
         'fenster' => {
                  'position_x' => '100',
                  'position_y' => '120',
                  'hoehe' => '352',
                  'breite' => '417'
               }
};

Die Variable $tree repräsentiert das Wurzelelement des Baums, <konfiguration>. Das Hash enthält Referenzen auf seine Kindelemente, <zeichensatz> und <fenster>. Wir erhalten diese Referenzen über die Elementnamen. Die Kindelemente sind ihrerseits wieder Hashes, die die dritte Elementebene repräsentieren. Auf dieser Ebene finden wir im Hash jeweils Strings als Werte, die den Texten entsprechen, wie wir sie in der Eingabedatei gefunden haben. Das gesamte Dokument besteht aus Hashreferenzen.

Dieses Beispiel war natürlich recht einfach. Ein großer Teil des Erfolgs von XML::Simple beruht darauf, daß das Modul eine einfache XML-Struktur annimmt. Wenn Sie die Eingabedatei noch einmal anschauen, werden Sie zum Beispiel feststellen, daß zwei Geschwisterelemente nie denselben Namen haben. Identische Namen wären mit Hashreferenzen alleine nur schwer abbildbar.

Glücklicherweise hat XML::Simple auch dafür eine Antwort. Wenn ein Element zwei oder mehr Kindelemente mit demselben Namen hat, wird eine Liste benutzt, die diese Kindelemente enthält und in einer Gruppe zusammenfaßt. Ändern wir die Konfigurationsdatei im nächsten Beispiel ein wenig ab.

Beispiel: Ein etwas komplexeres Beispiel einer Konfigurationsdatei

<konfiguration>
    <zeichensatz role="console">
        <groesse>9</groesse>
        <fname>Courier</fname>
    </zeichensatz>
    <zeichensatz role="default">
        <fname>Times New Roman</fname>
        <groesse>14</groesse>
    </zeichensatz>
    <zeichensatz role="titles">
        <groesse>10</groesse>
        <fname>Helvetica</fname>
    </zeichensatz>
</konfiguration>

Dieses Mal haben wir XML::Simple einen angeschnittenen Ball zugeworfen: Nacheinander gibt es nun drei <zeichensatz>-Elemente. Wie wird das Modul damit umgehen? Ein Dump der Datenstruktur gibt uns auch dieses Mal die Antwort.

$tree = {            
            'zeichensatz' => [
                      {
                        'fname' => 'Courier',
                        'groesse' => '9',
                        'role' => 'console'
                      },
                      {
                        'fname' => 'Times New Roman',
                        'groesse' => '14',
                        'role' => 'default'
                      },
                      {
                        'fname' => 'Helvetica',
                        'groesse' => '10',
                        'role' => 'titles'
                      }
                    ]
};

Der Wert des Schlüssels zeichensatz ist jetzt eine Arrayreferenz. Das Array enthält dieses Mal die Hashreferenzen, die die <zeichensatz>-Elemente repräsentieren. Um einen bestimmten Zeichensatz zu finden, muß man also durch die Liste iterieren bis man den gewünschten findet. Damit ist das Problem der Geschwister mit gleichen Namen gelöst.

Unsere veränderte Eingabedatei enthält erstmalig neben den Elementen auch Attribute. Diese Attribute wurden in die Datenstruktur eingebaut, als wären es Kindelemente ihres Vaterknotens. Natürlich kann es geschehen, daß es Attribute und Elemente mit demselben Namen gibt, aber dieses Problem wird auf dieselbe Weise gelöst wie das der Geschwister mit demselben Namen. Solange es nicht stört, daß Attribute und Elemente in einen Topf geworfen werden, ist das recht praktisch.

Wir haben gesehen, wie man XML-Dokumente lädt. Wie sieht es mit dem Schreiben aus? XML::Simple kennt eine Methode XMLout( ), mit der man XML-Dokumente ausgeben kann. Die auszugebenden Datenstrukturen erhält man entweder durch Modifikation einer zuvor gelesenen Struktur oder durch kompletten Neuaufbau. Wie wir gesehen haben, sind diese Strukturen nicht sehr kompliziert, und es ist deshalb ohne weiteres möglich, sie selbst zu erstellen.

Unsere Schlußfolgerung? XML::Simple funktioniert sehr gut mit einfachen XML-Dokumenten, sobald es ein wenig komplexer wird, bekommt man Probleme. Zum Beispiel ist es nicht möglich, Elemente zu behandeln, die sowohl Text als auch Kindelemente enthalten (sogenannter »mixed content«). Das Modul kennt bei der Eingabe nur die Knotentypen Element, Attribut und Text, dagegen fehlen Verarbeitungsanweisungen und CDATA-Abschnitte. Da Hashes die Reihenfolge ihrer Schlüssel verlieren, können Elemente durcheinandergeworfen werden. Wenn Sie das alles nicht stört, dann setzen Sie auf XML::Simple. Das was es soll, macht das Modul wunderbar , und es gibt keine einfachere Art und Weise, mit XML-Markup und den zugehörigen Datenstrukturen umzugehen.

  

  

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema Perl & XML bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © 2003 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "Perl & XML" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

O’Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de