Eine Basisklasse für Handler

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

SAX unterscheidet nicht zwischen verschiedenen Elementen. Diese Aufgabe bleibt Ihnen selbst überlassen. Der Elementname wird beispielsweise im Handler start_element( ) gelesen und auf einen Stack geschoben, damit wir die aktuelle Hierarchie der Elemente kennen. Das ist irgendwie immer dasselbe, und deshalb taucht schnell der Wunsch auf, diesen Vorgang etwas zu abstrahieren. Das ist es auch, was Ken MacLeods Modul XML::Handler::Subs leistet.

Das Modul definiert ein Objekt, das Handleraufrufe an mehr speziellere Handler delegiert. Sie möchten einen Handler, der sich nur mit <title>-Elementen beschäftigt? Schreiben Sie ihn, und er wird vom Modul aufgerufen. Die Auswahl geschieht über die Handlernamen: Handler für Start-Tags haben einen Namen, der mit s_ beginnt. Auf das Präfix folgt der Elementname, eventuelle Sonderzeichen werden durch einen Unterstrich ersetzt. (Zum Beispiel wäre s-start-tag kein gültiger Methodenname in Perl.) Analog beginnen die Handler der End-Tags mit e_.

Aber das ist noch nicht alles. Das Basisobjekt enthält außerdem einen eingebauten Stack sowie eine Accessormethode, durch die man überprüfen kann, ob man sich innerhalb eines vorgegebenen Elements befindet. Den Stack erhält man mit $self->{Names}, und die Methode wird mit in_element( $name ) aufgerufen, um herauszufinden, ob man sich gerade innerhalb eines Elements $name befindet.

Probieren wir es aus. Zu diesem Zweck brauchen wir ein Programm, das etwas Elementspezifisches tut. Wie nehmen eine HTML-Datei und geben alles aus, was innerhalb eines <h1>-Elements liegt, einschließlich eventueller Hervorhebungselemente. Der Quellcode dieses Beispiels ist atemberaubend einfach.

Beispiel: Ein von XML::Handler::Subs abgeleiteter Parser

use XML::Parser::PerlSAX;
use XML::Handler::Subs

#
# Initialisierung des Parsers
#
use XML::Parser::PerlSAX;
my $parser = XML::Parser::PerlSAX->new( Handler => H1_grabber->new( ) );
$parser->parse( Source => {SystemId => shift @ARGV} );

## Das Handlerobjekt: H1_grabber
##
package H1_grabber;
use base( 'XML::Handler::Subs' );
sub new {
    my $type = shift;
    my $self = {@_};
    return bless( $self, $type );
}

#
# Handler für Start des Dokuments
#
sub start_document {
    SUPER::start_document( );
    print "Inhaltsverzeichnis der Datei:\n";
}

#
# Start von <h1> behandeln: Gib ein Markierungszeichen aus
#
sub s_h1 {
    print "[";
}

#
# Ende von <h1>: weiteres Markierungszeichen und Zeilenende
#
sub e_h1 {
    print "]\n";
}    

#
# Behandlung von Textdaten
#
sub characters {
    my( $self, $props ) = @_;
    my $data = $props->{Data};
    print $data if( $self->in_element( h1 ));
}

Füttern wir dieses Programm mit einer Testdatei:

<html>
    <head><title>Das Leben des Brian</title></head>
    <body>
        <h1>Brians Mama</h1>
        <p>...</p>
        <h1>Die Steinigung</h1>
        <p>...</p>
        <h1>Brian trifft <em>Judith</em>!</h1>
        <p>...</p>
    </body>
</html>

Und das kommt dabei heraus:

Inhaltsverzeichnis der Datei:
[Brians Mama]
[Die Steinigung]
[Brian trifft Judith!]

Dank des Aufrufs von in_element( ) ist selbst der Text zu sehen, der innerhalb eines <em>-Elements stand. XML::Handler::Subs ist definitiv ein nützliches Modul, wenn man mit SAX arbeitet.

  

  

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