XML::Grove

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

Bevor wir uns wieder den standardorientierten Lösungen zuwenden, wollen wir noch als letztes Objektmodell Ken MacLeods XML::Grove anschauen. Wie XML::SimpleObject verwendet das Modul die Ausgabe von XML::Parser im Baummodus und wandelt sie in eine eigene Objektstruktur um. Der Unterschied besteht darin, daß jeder Knotentyp durch eine eigene Klasse repräsentiert wird. Ein Element ist ein Objekt der Klasse XML::Grove::Element, eine Verarbeitungsanweisung entspricht einer Instanz der Klasse XML::Grove::PI usw. Texte sind allerdings nach wie vor skalare Werte.

Ein Vorzug dieses Moduls ist es, daß die Deklarationen des internen Bereichs in Listen gespeichert werden, die über das XML::Grove-Objekt zugänglich sind. Jedes Entity und jede Notation steht für weitere Verwendungen zur Verfügung. Zum Beispiel zählt das folgende Programm die Verteilung der einzelnen Elemente und anderer Knoten. Anschließend wird eine Liste der Knotentypen und ihrer Zahl ausgegeben.

Zuerst initialisieren wir den Parser, wobei wir als Stil »grove« angeben. Damit teilen wir XML::Parser mit, daß seine Ausgabe mit dem Modul XML::Parser::Grove verarbeitet werden soll:

use XML::Parser;
use XML::Parser::Grove;
use XML::Grove;

my $parser = XML::Parser->new( Style => 'grove', NoExpand => '1' );
my $grove = $parser->parsefile( shift @ARGV );

Als nächstes greifen wir mit Hilfe der Methode contents( ) des Objekts $grove auf den Inhalt des Dokuments zu. Das Ergebnis ist eine Liste von Knoten, einschließlich des Wurzelelements sowie möglicher Kommentare und Verarbeitungsanweisungen, die außerhalb des Wurzelelements stehen. Eine Subroutine tabelle( ) zählt Knoten. Durch rekursive Aufrufe werden auch die Knoten von Kindelementen gezählt. Zum Schluß wird das Ergebnis ausgegeben:

# Tabelle über Elemente und andere Knoten erstellen
my %dist;
foreach( @{$grove->contents} ) {
   &tabulate( $_, \%dist );
}
print "\nGefundene Knoten:\n\n";
foreach( sort keys %dist ) {
   print "$_: " . $dist{$_} . "\n";
}

Es folgt nun die zum Zählen verwendete Subroutine. Da die Knoten unterschiedliche Typen haben, verwenden wir ref( ), um den Typ zu bestimmen. Attribute werden hier nicht als Knoten gezählt, sind aber über die Methode attributes( ) der Elementklasse als Hash zugänglich. Ein Aufruf der Methode contents( ) ermöglicht es, die Kindelemente analog zu verarbeiten:

# Ein Knoten und eine Tabelle werden übergeben. Finde heraus, um was für
# einen Knoten es sich handelt, und erhöhe den entsprechenden Zähler.
# Rekursiver Aufruf, falls notwendig
#
sub tabelle {   
   my( $node, $table ) = @_;
  
   my $type = ref( $node );
   if( $type eq 'XML::Grove::Element' ) {
      $table->{ 'element' }++;
      $table->{ 'element (' . $node->name . ')' }++;
      foreach( keys %{$node->attributes} ) {
      $table->{ "attribut ($_)" }++;
      }
      foreach( @{$node->contents} ) {
      &tabelle( $_, $table );
      }
     
   } elsif( $type eq 'XML::Grove::Entity' ) {
      $table->{ 'entity-ref (' . $node->name . ')' }++;
     
   } elsif( $type eq 'XML::Grove::PI' ) {
      $table->{ 'PI (' . $node->target . ')' }++;
     
   } elsif( $type eq 'XML::Grove::Comment' ) {
      $table->{ 'comment' }++;
     
   } else {
      $table->{ 'text-node' }++
   }
}

Hier sehen wir eine typische Ausgabe des Programms, angewendet auf eine XML-Datei:

Gefundene Knoten:
PI (a): 1
attribut (date): 1
attribut (style): 12
attribut (type): 2
element: 30
element (category): 2
element (inventory): 1
element (item): 6
element (location): 6
element (name): 12
element (note): 3
text-node: 100

  

  

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