XML::SimpleObject

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

Die Verwendung eingebauter Datentypen hat durchaus Vorzüge. Sie führt beim Umgang mit XML aber schnell zu kompliziertem und schwer lesbarem Quelltext. Wenn man das letzte Kind eines Elements finden oder die Darstellung der Daten ändern will, wünscht man sich schnell eine Objektschnittstelle herbei. Aus diesem Grund gibt es einige objektorientierte Module zum Thema XML, die es anzuschauen lohnt.

Wir beginnen unseren Streifzug durch die objektorientierten XML-Bäume mit Dan Brians Modul XML::SimpleObject. Dieses Modul nimmt die von XML::Parser im Baummodus generierte Datenstruktur als Eingabe und wandelt sie in eine Hierarchie aus Objekten um. Jedes Objekt steht für ein Element und bietet Zugriffsmethoden auf die Kindknoten. Wie bei XML::Simple greifen wir auf Kindelemente über ihre Namen zu, die wir dieses Mal allerdings an geeignete Methoden übergeben.

Was nützt uns dieses Modul? Das Beispiel unten ist eine einfache XML-Datei, die einen Stammbaum enthält. Wir wollen ein Programm schreiben, das diese Datei in einen Baum von Objekten umwandelt. Anschließend soll der Baum durchlaufen werden, um eine textuelle Beschreibung auszugeben.

Beispiel: Ein Stammbaum

<?xml version="1.0" encoding="ISO-8859-1"?>
<stammbaum>
    <nachkomme><name>Gluk der Große</name>
        <kinder>
            <nachkomme><name>Glim der Tapfere</name></nachkomme>
            <nachkomme><name>Gelbar der Starke</name></nachkomme>
            <nachkomme><name>Glurko der Gute</name>
                <kinder>
                    <nachkomme><name>Glurf der Ungeduldige</name></nachkomme>
                    <nachkomme><name>Glug der Merkwürdige</name>
                        <kinder>
                            <nachkomme><name>Blug der Kranke</name></nachkomme>
                            <nachkomme><name>Flug der Gestörte</name></nachkomme>
                        </kinder>
                    </nachkomme>
                </kinder>
            </nachkomme>
        </kinder>
    </nachkomme>
</stammbaum>

Das nächste Beispiel enthält unser Programm. Zunächst wird die Datei mit XML::Parser im Baummodus gelesen. Anschließend wird das Ergebnis an den Konstruktor von XML::SimpleObject übergeben. Als nächstes folgt eine Funktion schaueauf( ), die den Baum rekursiv durchlaufen und Text ausgeben soll. Für jedes <nachkomme>-Element wird der Name ausgegeben, und falls es seinerseits Nachkommen hat, wird der entsprechende Unterbaum ebenfalls durchlaufen. Zu diesem Zweck prüfen wir, ob die Methode child den Wert undef liefert oder nicht.

Beispiel: Ein mit XML::SimpleObject arbeitendes Programm

use XML::Parser;
use XML::SimpleObject;

# Lesen der Eingabedatei und Aufbau des Baums
my $file = shift @ARGV;
my $parser = XML::Parser->new( ErrorContext => 2, Style => "Tree" );
my $tree = XML::SimpleObject->new( $parser->parsefile( $file ));

# Ausgabe des Stammbaums
print "Mein Stammbaum beginnt mit ";
schaueauf( $tree->child( 'stammbaum' )->child( 'nachkomme' ), '' );

# Ausgabe einer Generation des Stammbaums
sub schaueauf {        
       my( $anc, $indent ) = @_;
  
       # Ausgabe des Namens des Vaters
       print $indent . $anc->child( 'name' )->value;
         
       # Falls Kinder vorhanden sind, gib sie ebenfalls aus
       if( $anc->child( 'kinder' ) and $anc->child( 'kinder' )->children ) {
       print ", Vater von...\n";
       my @children = $anc->child( 'kinder' )->children;
       foreach my $child ( @children ) {
            schaueauf( $child, $indent . ' ' );
       }
       } else {
           print "\n";
       }
}

Um zu demonstrieren, daß das Programm funktioniert, zeigen wir hier die Ausgabe. Zur besseren Lesbarkeit des Textes rückt das Programm die einzelnen Zeilen etwas ein:

Mein Stammbaum beginnt mit Gluk dem Großen, Vater von...    
    Glim der Tapfere
    Gelbar der Starke
    Glurko der Gute, Vater von...
        Glurf der Ungeduldige
        Glug der Merkwürdige, Vater von...
            Blug der Kranke
            Flug der Gestörte

Wir haben verschiedene Methoden verwendet, um auf die in den einzelnen Objekten enthaltenen Daten zuzugreifen. child( ) liefert eine Referenz auf eine Instanz von XML::SimpleObject, die ein Kindelement des aufgerufenen Knotens repräsentiert. children( ) liefert eine Liste aller solcher Referenzen. value( ) ergibt die Textdaten, die der aufgerufene Knoten enthält, das Ergebnis ist ein skalarer Wert. Falls man diesen Methoden Argumente übergibt, wird die Suche dadurch eingeschränkt. child( 'name' ) gibt zum Beispiel einen Repräsentanten des Elements <name> zurück, falls vorhanden. Anderenfalls ist das Ergebnis undef.

Das ist schon ein ganz guter Anfang. Wie der Name des Moduls aber andeutet, ist es für viele Anwendungen letzten Endes doch zu simpel. Die Möglichkeiten zum Zugriff auf einzelne Knoten sind begrenzt, im wesentlichen kann man ein Kindelement oder eine Liste solcher Kindelemente bekommen. Gibt es mehrere Elemente mit demselben Namen, bekommt man bereits Probleme.

Außerdem kennt das Modul keine Möglichkeit, den gelesenen Baum wieder in XML umzuwandeln. Durch seine Einfachheit ist das Modul aber gut geeignet, um objektorientierte Lösungen kennenzulernen.

  

  

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