Zur Hauptseite ... Zum Onlinearchiv ... Zum Abonnement ... Zum Newsletter ... Zu den Tools ... Zum Impressum ... Zum Login ...

Einlesen von XML-Dateien mit DOM

Access bietet mit steigender Versionsnummer mehr und mehr Möglichkeiten zum Import und Export von Daten im XML-Format. Wenn es allerdings um den Import von Daten aus einer XML-Datei in eine bestehende Datenstruktur handelt, helfen die automatisierten Importmöglichkeiten nur bedingt weiter. In dem Fall ist Handarbeit angesagt, und dabei hilft Ihnen unter VBA das Objektmodell DOM.

Beispieldatenbank

Die Beispieldatenbank enthält zwei Tabellen namens tblProjekte und tblProjektphasen sowie ein Modul mit den beschriebenen Funktionen. Außerdem finden Sie in der ZIP-Datei die Datei beispiel.xml.

DOM verfügbar machen

Um mit DOM (Abkürzung für das XML-Document Object Model) in VBA zu arbeiten, müssen Sie zunächst die entsprechende Bibliothek verfügbar machen. Dazu wechseln Sie zunächst in den VBA-Editor und zeigen dann mit dem Menüeintrag Extras/Verweise den Dialog Verweise an. Hier wählen Sie einen der vorhandenen Einträge Microsoft XML aus.

Öffnen eines XML-Dokuments

Bevor Sie die Daten in einem XML-Dokument lesen können, müssen Sie es zunächst öffnen. Die folgende Prozedur lädt ein XML-Dokument mit dem per Parameter übergebenen Dateinamen und ruft eine weitere Funktion namens XMLEinlesen auf, die zum Verarbeiten des Inhalts des XML-Dokuments dient:

Public Function XMLOeffnen(strDateiname As String)

    Dim MSXML As New MSXML2.DOMDocument

    With MSXML

        .async = False

        .preserveWhiteSpace = False

        .validateOnParse = True

        .resolveExternals = False

    End With

    If MSXML.Load(strDateiname) = True Then

        XMLOeffnen = XMLEinlesen(MSXML)

    Else

        XMLOeffnen = 0

    End If

End Function

Einlesen des XML-Dokuments

Die nachfolgenden Beschreibungen beziehen sich auf die Datei Beispiel.xml, die sich mit der Beispieldatenbank in der oben zum Download bereitstehenden ZIP-Datei befindet. Die XML-Datei hat den folgenden Inhalt:

<?xml version="1.0" encoding="ISO-8859-1" ?>

<projekte>

    <projektbezeichnung>Beispielprojekt 1</projektbezeichnung>

    <projektstart>1.1.2004</projektstart>

    <projektende>31.1.2004</projektende>

    <projektleiter>Andre Minhorst</projektleiter>

    <projektphasen>

      <projektphase projektphaseID="1">

        <projektphasenbezeichnung>Beispielphase 1</projektphasenbezeichnung>

        <projektphasenstart>1.1.2004</projektphasenstart>

        <projektphasenende>10.1.2004</projektphasenende>

      </projektphase>

      <projektphase projektphaseID="2">

        <projektphasenbezeichnung>Beispielphase 2</projektphasenbezeichnung>

        <projektphasenstart>11.1.2004</projektphasenstart>

        <projektphasenende>20.1.2004</projektphasenende>

      </projektphase>

    </projektphasen>

  <!--...weitere Projekte...-->

</projekte>

 

 

Die Beispieldatenbank enthält zwei Tabellen namens tblProjekte und tblProjektphasen. Den Aufbau der Tabellen zeigt Abbildung 1. In den nachfolgenden Schritten wird eine Funktion erstellt, die zum Parsen der XML-Datei und dem Eintragen der Informationen in die Tabellen der Datenbank dient.

Abbildung 1: Aufbau der Beispieltabellen

Ausgeben aller Daten

Wenn Sie einfach alle Daten hintereinander ausgeben möchten, erstellen Sie ein neues Objekt, mit dem Sie auf das äußerste, alle anderen Elemente umschließende Element verweisen. Anschließend geben Sie mit der Eigenschaft Text alle untergeordneten Elemente aus:

Public Function XMLEinlesen(objXMLDocument As MSXML2.DOMDocument)

    Dim objXMLDocumentElement As Object

    Set objXMLDocumentElement = objXMLDocument.documentElement

    Debug.Print objXMLDocument.Text

End Function

Zugreifen auf bestimmte Elemente

Um die Daten des XML-Dokuments einzulesen, wäre es praktisch, auf die einzelnen Elemente des Dokuments zugreifen zu können. Die folgende Funktion gibt alle Elemente des Typs Projekt aus. Dabei verwendet die Funktion die Methode GetElementsByTagName, um der Variablen objXMLChildNodes eine Auflistung der Elemente mit dem gesuchten Namen zuzuweisen.

Diese Auflistung kann dann komfortabel durchlaufen werden. Die Methode Text gibt innerhalb einer Schleife die Werte aller untergeordneten Elemente aus.

Public Function ProjekteAusgeben(strDateiname As String)

    Dim objXMLDocument As New MSXML2.DOMDocument

    Dim objXMLChildNodes As Object

    Dim objXMLChildNode As Object

    With objXMLDocument

        .async = False

        .preserveWhiteSpace = False

        .validateOnParse = True

        .resolveExternals = False

    End With

    If objXMLDocument.Load(strDateiname) = True Then

        Set objXMLChildNodes = _

            objXMLDocument.getElementsByTagName"projekt")

        For Each objXMLChildNode In objXMLChildNodes

            Debug.Print objXMLChildNode.Text

        Next objXMLChildNode

    Else

        MsgBox objXMLDocument.parseError.reason

    End If

End Function

Ausgeben von Elementinhalten und -eigenschaften

Wesentlich interessanter als die Auflistung aller unterhalb eines bestimmten Elements liegenden Inhalte ist die Ermittlung und Ausgabe von Elementinhalten und Elementeigenschaften.

Mit der nachfolgenden Beispielfunktion lernen einige Anweisungen und Eigenschaften kennen, die zum Auseinandernehmen einer XML-Datei erforderlich sind. Die Funktion öffnet wiederum zunächst das weiter oben beschriebene XML-Beispiel mit den Projektdaten.

Die Projektdaten sind in zwei Ebenen eingeteilt: in Projekte und in die den Projekten zugeordneten Projektphasen. Diese beiden Objekttypen werden durch die Funktion nacheinander durchlaufen.

Die Funktion setzt wiederum über die Variable objXMLDocumentElement einen Verweis auf das äußerste Element der Datei. Dann werden in einer For Next-Schleife alle untergeordneten Elemente durchlaufen. Um den Endpunkt der Schleife festzulegen, ermittelt der Ausdruck objXMLDocumentElement.childNodes.Item(i) die Anzahl der untergeordneten Elemente. Das jeweils aktuelle Element wird in der Variablen objXMLProjekt gespeichert, wobei der Bezug zu dem gewünschten Auflistungselement über die Item-Eigenschaft hergestellt wird.

Nach der Überprüfung, ob es sich bei dem Element um ein Projekt handelt, werden die einzelnen Unterelemente über die Methode selectSingleNode referenziert und deren Wert über die Eigenschaft Text ausgelesen. Auf diese Weise werden die Informationen über die Projektbezeichnung, Projektstart und -ende sowie den Projektleiter ermittelt.

Etwas anders erfolgt der Zugriff auf die ProjektID, die als Eigenschaft des Projekt-Elements selbst gespeichert wird: Der Zugriff erfolgt hier über die Methode getAttribute, die als Parameter den Eigenschaftsnamen erfordert.

Die Projektphasen sind den Projekten untergeordnet. Es kann je Projekt beliebig viele Projektphasen geben, daher sind diese in einem eigenen Knoten aufgelistet. Nach einer Überprüfung, ob der Knoten vorhanden ist, werden die enthaltenen Projektphasen durchlaufen und die Informationen ähnlich wie bereits bei den Projekten ausgegeben.

Public Function ProjekteAusgeben(strDateiname As String)

  Dim objXMLDocument As New MSXML2.DOMDocument

  Dim objXMLDocumentElement As Object

  Dim objXMLProjekt As Object

  Dim objXMLProjektphase As Object

  Dim objXMLProjektleiter As Object

  Dim i As Integer

  Dim j As Integer

  With objXMLDocument

    .async = False

    .preserveWhiteSpace = False

    .validateOnParse = True

    .resolveExternals = False

  End With

  If objXMLDocument.Load(strDateiname) = True Then

    Set objXMLDocumentElement = objXMLDocument.documentElement

    For i = 0 To objXMLDocumentElement.childNodes.length - 1

      Set objXMLProjekt = objXMLDocumentElement.childNodes.Item(i)

      If objXMLProjekt.nodeName = "projekt" Then

        Debug.Print "ProjektID: " _

          & objXMLProjekt.getAttribute("projektID")

        Debug.Print "Bezeichnung: " _

          & objXMLProjekt.selectSingleNode("projektbezeichnung").Text

        Debug.Print "Leitung: " _

          & objXMLProjekt.selectSingleNode("projektleiter").Text

        Debug.Print "Start: " _

          & objXMLProjekt.selectSingleNode("projektstart").Text

        Debug.Print "Ende: " _

          & objXMLProjekt.selectSingleNode("projektende").Text

        Set objXMLProjektphasen = _

          objXMLProjekt.selectSingleNode("projektphasen")

        If Not objXMLProjektphasen Is Nothing Then

          For j = 0 To objXMLProjektphasen.childNodes.length - 1

            Set objXMLProjektphase = _

              objXMLProjektphasen.childNodes.Item(j)

            If objXMLProjektphase.nodeName = "projektphase" Then

              Debug.Print "  ProjektphaseID: " _

                & objXMLProjektphase.getAttribute("projektphaseID")

              Debug.Print "  Bezeichnung: " _

                & objXMLProjektphase. _

                selectSingleNode("projektphasenbezeichnung").Text

              Debug.Print "  Start: " _

                & objXMLProjektphase. _

                selectSingleNode("projektphasenstart").Text

              Debug.Print "  Ende: " _

                & objXMLProjektphase. _

                selectSingleNode("projektphasenende").Text

            End If

          Next j

        End If

      End If

    Next i

  Else

    MsgBox objXMLDocument.parseError.reason

  End If

End Function

Übernehmen der Daten der XML-Datei in die Datenbank

Um die eingelesenen Daten in die Datenbank zu übernehmen, müssen Sie diese lediglich in geeigneter Weise in die beiden Tabellen der Datenbank schreiben. Die folgende Funktion entspricht vom Aufbau her der Funktion ProjekteAusgeben. Sie gibt aber keinerlei Daten im Testfenster aus, sondern schreibt diese direkt in die beiden Tabellen tblProjekte und tblProjektphasen.

Achtung: Die Funktion enthält keinerlei Mechanismen, die das Vorhandensein der ProjektIDs und ProjektphasenIDs überprüfen. Wenn die gleiche ID also zweimal in eine Tabelle geschrieben wird, erzeugt dies einen Fehler.

Public Function ProjekteSchreiben(strDateiname As String)

  Dim objXMLDocument As New MSXML2.DOMDocument

  Dim objXMLDocumentElement As Object

  Dim objXMLProjekt As Object

  Dim objXMLProjektphase As Object

  Dim objXMLProjektleiter As Object

  Dim cnn As ADODB.Connection

  Dim rstProjekte As New ADODB.Recordset

  Dim rstProjektphasen As New ADODB.Recordset

  Dim i As Integer

  Dim j As Integer

  Dim intProjektID As Integer

  Set cnn = CurrentProject.Connection

  rstProjekte.Open "tblProjekte", cnn, adOpenDynamic, adLockOptimistic

  rstProjektphasen.Open "tblProjektphasen", cnn, adOpenDynamic, _

    adLockOptimistic

  With objXMLDocument

    .async = False

    .preserveWhiteSpace = False

    .validateOnParse = True

    .resolveExternals = False

  End With

  If objXMLDocument.Load(strDateiname) = True Then

    Set objXMLDocumentElement = objXMLDocument.documentElement

    For i = 0 To objXMLDocumentElement.childNodes.length - 1

      Set objXMLProjekt = objXMLDocumentElement.childNodes.Item(i)

      If objXMLProjekt.nodeName = "projekt" Then

        With rstProjekte

          .AddNew

          intProjektID = objXMLProjekt.getAttribute("projektID")

          !ProjektID = intProjektID

          !Projektbezeichnung = _

            objXMLProjekt.selectSingleNode("projektbezeichnung").Text

          !Projektleiter = _

            objXMLProjekt.selectSingleNode("projektleiter").Text

          !Projektstart = _

            objXMLProjekt.selectSingleNode("projektstart").Text

          !ProjektEnde = _

            objXMLProjekt.selectSingleNode("projektende").Text

          .Update

        End With

        Set objXMLProjektphasen = objXMLProjekt. _

          selectSingleNode("projektphasen")

        If Not objXMLProjektphasen Is Nothing Then

          For j = 0 To objXMLProjektphasen.childNodes.length - 1

            Set objXMLProjektphase = _

              objXMLProjektphasen.childNodes.Item(j)

            If objXMLProjektphase.nodeName = "projektphase" Then

              With rstProjektphasen

                .AddNew

                !ProjektphaseID = _

                  objXMLProjektphase.getAttribute("projektphaseID")

                !ProjektID = intProjektID

                !Projektphasenbezeichnung = _

                  objXMLProjektphase. _

                  selectSingleNode("projektphasenbezeichnung").Text

                !Projektphasenstart = _

                  objXMLProjektphase. _

                  selectSingleNode("projektphasenstart").Text

                !ProjektphasenEnde = _

                  objXMLProjektphase. _

                  selectSingleNode("projektphasenende").Text

                .Update

              End With

            End If

          Next j

        End If

      End If

    Next i

  Else

    MsgBox objXMLDocument.parseError.reason

  End If

  rstProjektphasen.Close

  rstProjekte.Close

  Set rstProjektphasen = Nothing

  Set rstProjekte = Nothing

  Set cnn = Nothing

End Function

 

 

© 2003-2010 André Minhorst Alle Rechte vorbehalten.