SAX-Parser - Die Klasse HandlerBase

Nehmen wir einmal an, ihr wollt aus irgendwelchen merkwürdigen Gründen, oder weil ihr einfach Lust habt, oder weil ich ein Beispiel brauche, ein kleines Programm schreiben, das ein XML-Dokument parst, und dabei die Elemente und die Fehler zählt. Wie könnte man das realisieren?

Ihr könntet nun natürlich einen Documenthandler schreiben, in dem nur die startElement-Methode etwas sinnvolles macht (nämlich einen Counter hochzählen), und alle anderen Methoden trivial sind, also garnichts tun. Außerdem braucht ihr noch einen Errorhandler, um die Fehler zu zählen. Die anderen Methoden des Errorhandlers sind wiederum überflüssig, müssen aber natürlich implementiert sein.

Das ist eine Menge Arbeit, wenn man eigentlich nur zwei Methoden braucht! Aber ihr habt Glück, die Programmierer der Parser haben sich ähnliches gedacht, und die Klasse HandlerBase zur Verfügung gestellt.

Wie funktioniert diese Klasse nun? Die HandlerBase ist eine Zusammenfassung verschiedener Evenhandler, darunter auch ErrorHandler und DocumentHandler, in der alle Methoden dieser Eventhandler trivial implementiert sind. Das bedeutet, ihr könnt diese Klasse einfach ableiten, und braucht dann nurnoch die Methoden überlagern, die ihr benötigt.

Ich glaube ein Beispiel wäre jetzt ganz hilfreich:

import org.xml.sax.*;

public class MyHandlerBase extends HandlerBase
{
    public int elements = 0;
    public int errors = 0;

    public void startElement(String name, AttributeList attrs)
    {
        elements++;
    }

    public void error(SAXParseException e)
    {
        errors++;
    }
}

Wie ihr seht, mußten nur die Methoden implementiert werden, die ihr auch benötigt. Praktische Sache das. Aber ihr solltet aufpassen, daß die Übersichtlichkeit gewahrt bleibt. Unter Umständen, ist es besser die Handler einzeln zu implementieren.

Beim Parser wird das ganze nun wie folgt registriert:

MyHandlerBase mhb = new MyHandlerBase();
parser.setDocumentHandler(mhb);
parser.setErrorHandler(mhb);

Wenn die Programme klein und übersichtlich sind, könnt ihr natürlich auch alles in eine Klasse schreiben:

import com.ibm.xml.parsers.*;
import org.xml.sax.*;

public class Counter extends HandlerBase
{
    private int elements = 0;
    private int errors = 0;


    public static void main(String[] args)
    {
        Counter counter = new Counter();
        counter.count(args[0]);
    }

    public void count(String file)
    {
        SAXParser parser = new SAXParser();
        parser.setDocumentHandler(this);
        parser.setErrorHandler(this);
        try
        {
            parser.parse(file);
        }
        catch (Exception e)
        {
            System.err.printl("Fehler beim parsen: ");
            System.err.println(e);
        }
        System.out.println("Elemente: " + elements);
        System.out.println("Errors  : " + errors);
    }

    public void error(SAXParseException e)
    {
        errors++;
    }

    public void startElement(String name, AttributeList attrs)
    {
        elements++;
    }
}

Der Vollständigkeit halber sei noch vermerkt, daß das Programm mit dem Sun-Parser fast gleich aussieht. Trotzdem hier das ganze nochmal mit diesem Parser:

import com.sun.xml.parser.Parser;
import com.sun.xml.parser.Resolver;
import org.xml.sax.*;
import java.io.File;

public class Counter extends HandlerBase
{
    private int elements = 0;
    private int errors = 0;


    public static void main(String[] args)
    {
        Counter counter = new Counter();
        counter.count(args[0]);
    }

    public void count(String file)
    {
        Parser parser = new Parser();
        parser.setDocumentHandler(this);
        parser.setErrorHandler(this);
        try
        {
            parser.parse(Resolver.createInputSource(new File(file)));
        }
        catch (Exception e)
        {
            System.err.println("Fehler beim parsen: ");
            System.err.println(e);
        }
        System.out.println("elements: " + elements);
        System.out.println("errors  : " + errors);
    }

    public void error(SAXParseException e)
    {
        errors++;
    }

    public void startElement(String name, AttributeList attrs)
    {
        elements++;
    }
}

zurück              weiter

nach oben