XML-Dokumente mit SAX parsen

Wenn Sie ein Abonnement des Magazins 'Access im Unternehmen' besitzen, können Sie sich anmelden und den kompletten Artikel lesen.
Anderenfalls können Sie das Abonnement hier im Shop erwerben.

XML-Dokumente mit SAX parsen

Wir haben uns bereits in vielen Beiträgen mit dem Parsen von XML-Dokumenten befasst. Dabei haben wir immer den DOM-Parser verwendet, um die im XML-Dokument enthaltenen Daten zu lesen. In diesem Beitrag schauen wir uns eine Alternative namens SAX an. Während DOM das komplette XML-Dokument in den Speicher liest und darauf zugreift, liest SAX das Dokument zeilenweise ein. Im Folgenden erfahren Sie, welche Vor- und Nachteile die beiden Methoden haben und wie Sie mit SAX arbeiten können.

Der DOM-Parser liest ein vollständiges XML-Dokument in den Speicher ein und kann dafür auf alle enthaltenen Elemente zugreifen. Sie können die Elemente damit nacheinander durchlaufen oder mithilfe von XPATH-Ausdrücken und Methoden wie SelectSingleNode oder SelectNodes nach bestimmten Elementen im Dokumentbaum suchen.

Sie können damit im Dokumentbaum vor- und zurückspringen oder die enthaltenen Elemente hierarchisch durchlaufen.

DOM: Vor- und Nachteile

Der Nachteil liegt auf der Hand: Da der komplette Baum im Speicher liegt und mitunter verschachtelt ist, kann der Zugriff auf die Inhalte recht schnell zu Lasten der Performance gehen.

Ein weiterer Nachteil ist, dass sehr große XML-Dateien möglicherweise nicht in den Speicher passen und somit nicht geladen werden können. Dafür können Sie mit DOM aber nicht nur gezielt auf einzelne Elemente zugreifen, sondern den Dokumentbaum und die Inhalte auch bearbeiten.

SAX: Schnell, aber unflexibel

Anders sieht es bei SAX aus. Der SAX-Parser liest das Dokument Zeile für Zeile ein und bietet die Möglichkeit, auf die jeweilige Zeile zuzugreifen. Dabei ist der SAX-Parser rasend schnell! Allerdings liest er auch nur in einer Richtung, ein Hin- und Herspringen oder gar das gezielte Einlesen eines einzelnen Elements ohne Durchlaufen des XML-Dokuments bis zu diesem Punkt ist nicht möglich.

Außerdem können Sie mit dem SAX-Parser keine Änderungen am XML-Dokument vornehmen.

Vorbereitungen

Um den SAX-Parser nutzen zu können, benötigen Sie einen Verweis auf die Objektbibliothek Microsoft XML v6.0 (s. Bild 1).

Setzen eines Verweises auf die Bibliothek Microsoft XML, v6.0

Bild 1: Setzen eines Verweises auf die Bibliothek Microsoft XML, v6.0

Funktionsweise des SAX-Parsers

Wie aber greift der SAX-Parser nun auf das XML-Dokument zu? Öffnet er es wie ein Textdokument und liest dann etwa in einer Schleife die einzelnen Zeilen in eine Variable ein, auf deren Inhalt wir dann per VBA zugreifen können?

Mitnichten: Der SAX-Parser basiert auf Ereignissen. Das heißt, dass es verschiedene Ereignisse gibt:

  • documentLocator(ByVal RHS As MSXML2.IVBSAXLocator): Liefert Informationen etwa über den Speicherort des Dokuments.
  • startDocument(): Wird zu Beginn des Einlesevorgangs ausgelöst.
  • startPrefixMapping(strPrefix As String, strURI As String): Wird beim Einlesen der Namespace-Informationen ausgelöst und liefert mit strPrefix das Kürzel für den NameSpace (zum Beispiel xsi oder xsd) und mit strURI die jeweilige URI.
  • startElement(strNamespaceURI As String, strLocalName As String, strQName As String, ByVal oAttributes As MSXML2.IVBSAXAttributes): Wird für den Start eines jeden Elements ausgelöst (also etwa für ) und liefert mit strNameSpaceURI den Namespace, mit strLocalName den Namen des Elements und mit oAttributes ein Element, mit dem sich die Attribute des Elements auslesen lassen.
  • characters(strChars As String): Wird beim Einlesen eines Teils des Inhalts ausgelöst und liefert mit strChars den Inhalt. Dabei werden immer alle Zeichen geliefert, also auch die Zeilenumbrüche zwischen zwei Elementen, die Einrückungen und natürlich auch die tatsächlichen Inhalte der Elemente.
  • endElement(strName­spaceURI As String, strLocalName As String, strQName As String): endElement wird ausgelöst, wenn das Ende des Elements erreicht wird, also etwa . Die Parameter liefern die bereits weiter oben beschriebenen Werte.
  • endPrefix­Map­ping(str­Prefix As String): Wird ausgelöst, wenn das schließende Element zu dem Element erreicht wird, das eine Namespace-Angabe enthielt.
  • endDocument(): Wird nach der Abarbeitung des letzten Elements ausgelöst.

Die übrigen Ereignisse benötigen wir für die Beispiele dieses Beitrags nicht.

Ereignisse implementieren

Wie implementieren wir diese Ereignisse nun? Als Erstes erstellen Sie ein neues Klassenmodul namens clsSAX. Normalerweise würde man diesem nun eine entsprechende Objektvariable hinzufügen, die mit dem Schlüsselwort WithEvents deklariert wird und so die enthaltenen Ereignisprozeduren verfügbar macht.

In diesem Fall ist dies anders: Wir deklarieren keine Objektvariable, sondern legen mit der Implements-Anweisung fest, dass die Klasse alle Ereignisprozeduren eines speziellen Interfaces implementiert – in diesem Falle für das Interface MSXML2.IVBSAXContentHandler (s. Bild 2).

Implementieren der Klasse IVBSAXContentHandler

Bild 2: Implementieren der Klasse IVBSAXContentHandler

Dessen Ereignisse können Sie dann jedoch genau wie bei mit WithEvents deklarierten Objekten mit den beiden Kombinationsfeldern im oberen Bereich des Codefensters festlegen. Als Erstes fügen wir so das Ereignis startDocument hinzu (s. Bild 3).

Implementieren eines Ereignisses der Klasse IVBSAXContentHandler

Bild 3: Implementieren eines Ereignisses der Klasse IVBSAXContentHandler

Im Gegensatz zu mit Objekten, die Ereignisse auslösen, müssen Sie jedoch bei der Implementierung eines Interfaces alle Elemente anlegen. Anderenfalls löst das Debuggen des VBA-Projekts den Fehler aus Bild 4 aus. Wenn Sie alle Ereignisprozeduren hinzugefügt haben, ist der erste Teil erledigt.

Die Implementierung der Klasse IVBSAXContentHandler ist noch nicht vollständig.

Bild 4: Die Implementierung der Klasse IVBSAXContentHandler ist noch nicht vollständig.

Nun liegt uns allerdings zunächst einmal eine Klasse vor, die allein noch nichts ausrichtet. Wir müssen zunächst ein Objekt auf Basis dieser Klasse deklarieren und instanzieren sowie der Klasse mitteilen, dass sie in Aktion treten soll.

Dies erledigen wir gleich einmal in einem Formular, das auch die Steuerelemente zum Auswählen der zu untersuchenden XML-Datei sowie eine Schaltfläche zum Starten des Vorgangs enthalten soll. Dieses Formular sieht im ersten Entwurf wie in Bild 5 aus. Die Schaltfläche Einlesen soll das angegebene XML-Dokument mithilfe der Klasse clsSAX einlesen.

Das Formular frmSAX

Bild 5: Das Formular frmSAX

Dazu legen Sie die Ereignisprozedur aus Listing 1 an. Die Prozedur deklariert gleich zwei Objektvariablen: objSax soll ein Objekt auf Basis der soeben erstellten Klasse clsSAX aufnehmen. objReader nimmt ein Objekt des Typs SAXXMLReader60 auf, das Teil der Objektbibliothek Microsoft XML, v6.0 ist.

Private Sub cmdEinlesen_Click()
     Dim objReader As SAXXMLReader60
     Dim objSax As clsSAX
     Set objReader = New SAXXMLReader60
     Set objSax = New clsSAX
     Set objReader.contentHandler = objSax

Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.

Bitte geben Sie die Zeichenfolge in das nachfolgende Textfeld ein

Die mit einem * markierten Felder sind Pflichtfelder.

Neues aus unseren Magazinen
Listenfeld: Reihenfolge mehrerer Einträge...

Wir haben bereits in mehreren Beiträgen beschrieben, wie Sie die individuelle Reihenfolge von Elementen einer Tabelle über den Inhalt eines Feldes etwa namens »ReihenfolgeID« einstellen können –... [mehr]

Diagramme mit gefilterten Daten

In Ausgabe 2/2019 haben wir in zwei Artikeln die modernen Diagramme von Access vorgestellt. Im vorliegenen Beitrag zeigen wir Ihnen, wie Sie diese abhängig von den in einem Formular angezeigten... [mehr]

Benutzerverwaltung mit verschlüsselten...

Wenn Sie in einer Access-Anwendung Benutzer verwalten wollen, die sich per Benutzername und Kennwort an die Anwendung anmelden, sollten Sie sehr sensibel mit den in der Anwendung gespeicherten... [mehr]

HTML-Tabellen mit fester Kopfzeile

In den vorherigen Ausgaben von Access im Unternehmen und in der aktuellen Ausgabe arbeiten wir in einigen Beiträgen mit dem Webbrowser-Steuerelement und stellen Daten, die wir mit den Bordmitteln... [mehr]

Flexible HTML-Tabellen mit fester Kopfzeile

Im Beitrag »HTML-Tabellen mit fester Kopfzeile« haben wir gezeigt, wie Sie Daten aus einer bestimmten Abfrage in einem Webbrowser-Steuerelement so anzeigen, dass die Spaltenköpfe oben fixiert... [mehr]

Berechtigungen per HTML verwalten

Im Beitrag »Benutzerverwaltung mit verschlüsselten Kennwörtern« stellen wir eine Lösung vor, in der wir die Berechtigungen von Benutzergruppen an Datenbankobjekten definieren. Dort benötigen wir... [mehr]

Benutzer und Berechtigungen ermitteln

In den Beiträgen »Benutzerverwaltung mit verschlüsselten Kennwörtern« und »Berechtigungen per HTML verwalten« haben wir die Voraussetzungen für eine Benutzerverwaltung geschaffen. Im vorliegenden... [mehr]

Zugriffsrechte mit Datenmakros

Es gibt verschiedene Möglichkeiten, auf Basis des aktuell angemeldeten Benutzers sicherzustellen, dass dieser nur die für ihn vorgesehenen Aktionen mit Daten durchführen darf – beispielsweise durch... [mehr]

Kennwörter generieren

Für den einen oder anderen Zweck möchten Sie vielleicht Kennwörter generieren oder in einer Benutzeroberfläche die Möglichkeit zum Generieren von Kennwörtern anbieten. Wenn Sie etwa Benutzer zu... [mehr]

Neuer Datensatz von Frontend zu Backend

Für manche Themen gibt es keine kurze, prägnante Überschrift. In diesem Fall wollen wir zeigen, wie Sie einen neuen Datensatz anlegen, der in einer temporären Tabelle im Frontend gespeichert wird,... [mehr]