XML-Code-Builder

Ein XML-Code-Builder – was soll das denn sein Nun: Stellen Sie sich einfach vor, Ihr Kunde liefert Ihnen eine Datenbank und ein XML-Dokument und möchte, dass Sie ihm den Code liefern, mit dem er ein so aufgebautes XML-Dokument mit Daten aus der Datenbank füllen kann. Kein Problem, sagen Sie – es ist zwar etwas Fleißarbeit, aber das bekommen Sie schon hin. Ach: Ist Fleißarbeit nicht das erklärte Feindbild eines Access-Entwicklers Genau! Und deshalb liefert dieser Beitrag Ihnen die Werkzeuge, um das Grundgerüst des zu erstellenden Codes aufzubauen.

Mir ist das schon einige Male untergekommen: Ein Kunde möchte Daten aus seiner Datenbank in das XML-Format übertragen, weil dies die einzige Möglichkeit ist, die Daten an eine weitere Anwendung, einen Webservice und so weiter zu übergeben. Bereits nach dem Zusammenstellen der ersten paar Zeilen Code war klar: Das lässt sich automatisieren, zumindest für das Grundgerüst. Dass da noch ein wenig Handarbeit nötig ist, war klar, aber zumindest das Kopieren und Einfügen bestehender Codesegmente und das Anpassen an die jeweils zu schreibenden XML-Elemente auf Basis der Tabellenfelder ist erstens zu mühsam und zweitens zu fehleranfällig.

Also toben wir uns lieber an ein paar schicken VBA-Routinen aus, die uns den Großteil der Arbeit abnehmen. Was ist das Ziel der Lösung, die wir in diesem Beitrag vorstellen Stellen Sie sich vor, Sie sollten aus der Südsturm-Datenbank heraus einen Export fahren, der etwa in einen Onlineshop importiert werden soll. Das XML-Dokument zum Übertragen der Artikeldaten zum Onlineshop soll dann beispielsweise so aussehen, wie ein Beispieldokument verrät:

<xml version="1.0">
<Katalog>
    <Datum>11.07.2011</Datum>
    <Zeit>12:29:49</Zeit>
    <Artikelliste>
        <Artikel ID="1">
            <Artikelname>Artikel 1</Artikelname>
            <Waehrung>EUR</Waehrung>
            <Einzelpreis>10,00</Einzelpreis>
        </Artikel>
        <Artikel ID="2">
            <Artikelname>Artikel 2</Artikelname>
            <Waehrung>EUR</Waehrung>
            <Einzelpreis>20,00</Einzelpreis>
        </Artikel>
        ...
    </Artikelliste>
</Katalog>

Sie müssen nun Code schreiben, der erstens die Basiselemente wie die XML-Auszeichnung und die Elemente Katalog, Datum, Zeit und Artikelliste erzeugt. Danach folgt eine Schleife über alle Einträge der Tabelle tblArtikel, in der für jeden Artikel ein Artikel-Element sowie die darunter befindlichen Elemente angelegt werden.

Im Detail würde bereits zum Erstellen dieses einfachen XML-Dokuments die Prozedur aus Listing 1 nötig sein. Die Prozedur erstellt zunächst die Kopfdaten, danach folgen die Elemente Katalog und Artikelliste sowie in einer Do While-Schleife über alle Artikel die Elemente Artikel (mit dem Attribut ID), Artikelname, Waehrung und Einzelpreis. Um die Struktur abzubilden, legt die Prozedur jeweils die übergeordneten Elemente an, speichert einen Verweis auf diese Elemente in einer entsprechenden Objektvariablen und verwendet diese dann, um weitere Elemente unterzuordnen. Das bedeutet, dass Sie prinzipiell für jeden Elementtyp eine Objektvariable erzeugen müssen, in deren Kontext dann die untergeordneten Elemente erstellt werden können.

Listing 1: Zusammenstellen eines XML-Dokuments mit Artikeldaten

Public Sub Katalog()
    Dim db As DAO.Database
    Dim rst As DAO.Recordset
    Dim objXML As MSXML2.DOMDocument
    Dim objPI As MSXML2.IXMLDOMProcessingInstruction
    Dim objKatalog As MSXML2.IXMLDOMElement
    Dim objDatum As MSXML2.IXMLDOMElement
    Dim objZeit As MSXML2.IXMLDOMElement
    Dim objArtikelliste As MSXML2.IXMLDOMElement
    Dim objArtikel As MSXML2.IXMLDOMElement
    Dim objArtikelname As MSXML2.IXMLDOMElement
    Dim objWaehrung As MSXML2.IXMLDOMElement
    Dim objEinzelpreis As MSXML2.IXMLDOMElement
    Set db = CurrentDb
    Set rst = db.OpenRecordset("SELECT * FROM tblArtikel", dbOpenDynaset)
    Set objXML = New MSXML2.DOMDocument
    Set objPI = objXML.createProcessingInstruction("xml", "version=""1.0"" encoding=""utf-8""")
    objXML.appendChild objPI
    Set objKatalog = objXML.createElement("Katalog")
    objXML.appendChild objKatalog
    Set objDatum = objXML.createElement("Datum")
    objKatalog.appendChild objDatum
    objDatum.Text = Date
    Set objZeit = objXML.createElement("Zeit")
    objKatalog.appendChild objZeit
    objZeit.Text = Time
    Set objArtikelliste = objXML.createElement("Artikelliste")
    objKatalog.appendChild objArtikelliste
    Do While Not rst.EOF
         Set objArtikel = objXML.createElement("Artikel")
        objArtikelliste.appendChild objArtikel
        objArtikel.setAttribute "ID", rst!ArtikelID
        Set objArtikelname = objXML.createElement("Artikelname")
        objArtikel.appendChild objArtikelname
        objArtikelname.Text = rst!Artikelname
        Set objWaehrung = objXML.createElement("Waehrung")
        objArtikel.appendChild objWaehrung
        objWaehrung.Text = "EUR"
        Set objEinzelpreis = objXML.createElement("Einzelpreis")
        objArtikel.appendChild objEinzelpreis
        objEinzelpreis.Text = rst!Einzelpreis
        rst.MoveNext
    Loop
    Debug.Print FormatXML(objXML.XML)
End Sub

Verweis auf die XML-Bibliothek

Damit Sie die notwendigen Routinen zum Erstellen und Auslesen der XML-Dokumente unter Zuhilfenahme von IntelliSense erstellen können, brauchen Sie einen Verweis auf die Bibliothek Microsoft XML, vx.0. Diesen fügen Sie über den Verweise-Dialog hinzu, den Sie mit dem Menüeintrag Extras|Verweise öffnen.

Vereinfachung der Code-Erstellung

Der erste Schritt auf dem Weg zu einer massiven Vereinfachung der Erstellung von Code zum Produzieren von XML-Dokumenten sind Routinen, welche die immer wiederkehrenden Befehle kapseln.

Verarbeitungsanweisung hinzufügen

Ein XML-Dokument enthält in der Regel die folgende Zeile:

<xml version="1.0">

Um diese Zeile zu einem jungfräulichen XML-Dokument hinzuzufügen, das mit einer entsprechenden DOMDocument-Variablen referenziert wird, verwenden Sie die Prozedur aus Listing 2. Die Prozedur fügt der mit dem als Parameter übergebenen XML-Dokument die gewünschte Zeile hinzu. Um ein Dokument nur mit der Verarbeitungsanweisung auszustatten, benötigen Sie nun nur noch die folgende kleine Prozedur:

Listing 2: Erstellen der Verarbeitungsanweisung eines XML-Dokuments

Public Sub AddPI(objXML As MSXML2.DOMDocument)
    Dim objPI As MSXML2.IXMLDOMProcessingInstruction
    Set objPI = objXML.createProcessingInstruction("xml", "version=""1.0"" encoding=""utf-8""")
    objXML.appendChild objPI
End Sub
Public Sub DokumentMitPI()
    Dim objXML As MSXML2.DOMDocument
    Set objXML = New MSXML2.DOMDocument
    AddPI objXML
    Debug.Print objXML.XML
End Sub

Diese Prozedur erstellt das XML-Dokument, fügt die Verarbeitungsanweisung hinzu und gibt das Dokument im Direktfenster aus.

Elemente hinzufügen

Nun folgen die eigentlichen Elemente des XML-Dokuments. Zum Hinzufügen eines einfachen Elements benötigen Sie eigentlich die folgenden beiden Anweisungen:

Set objKatalog = objXML.createElement("Katalog")
objXML.appendChild objKatalog

Damit fügen Sie ein Element mit dem Namen Katalog als Root-Element hinzu, das jedoch noch keinen Inhalt besitzt:

<xml version="1.0">
<Katalog/>

Um diesem Element das Element Artikelliste unterzuordnen, legen Sie das Element im Kontext von objXML an, hängen es aber mit appendChild an das Element objKatalog an:

Set objArtikelliste = objXML.
createElement("Artikelliste")
objKatalog.appendChild objArtikelliste

Das Result sieht dann so aus:

<xml version="1.0">
<Katalog><Artikelliste/></Katalog>

Das Anhängen der Artikel-Elemente geschieht genau so, beim Element Artikelname kommt jedoch noch ein Inhalt hinzu – genau genommen ein Text:

Set objArtikelname = objXML. createElement("Artikelname")
objArtikel.appendChild objArtikelname
objArtikelname.Text = rst!Artikelname

Dazu speichern Sie wiederum den Verweis auf das Element und verwenden dann dessen Text-Eigenschaft, um den Inhalt hinzuzufügen. Wie wäre es, diese Objekte – egal, ob mit oder ohne Text – sämtlich mit Einzeilern anzulegen Schauen Sie sich einmal die Prozedur aus Listing 3 an. Diese erwartet drei Parameter:

Listing 3: Erstellung der Elemente des XML-Dokuments

Public Function CreateSubElement(objElement As Object, strElementname As String, Optional strText As String) As MSXML2.IXMLDOMElement
    Dim strTypename As String
    Dim objDocument As MSXML2.DOMDocument
    Dim objXMLElement As MSXML2.IXMLDOMElement
    strTypename = TypeName(objElement)
    Select Case strTypename
        Case "DOMDocument"
            Set objXMLElement = objElement.createElement(strElementname)
            objElement.appendChild objXMLElement
        Case "IXMLDOMElement"
            Set objDocument = objElement.ownerDocument
            Set objXMLElement = objDocument.createElement(strElementname)
            objElement.appendChild objXMLElement
    End Select
    If Len(strText) > 0 Then
        objXMLElement.Text = strText
    End If
    Set CreateSubElement = objXMLElement
End Function
  • objElement: Verweis auf das Element, unterhalb dessen das neue Element angelegt werden soll
  • strElementname: Name des neuen Elements, also beispielsweise Katalog, Artikelliste oder Artikel
  • strText: Text, den das Element enthalten soll, also beispielsweise Artikelname, Währung oder Einzelpreis

Sie können als objElement sowohl das Dokument selbst übergeben als auch ein bestehendes Element. Um dem mit objXML referenzierten Dokument die ersten vier Elemente Katalog, Artikelliste, Artikel und Artikelname samt Inhalt hinzuzufügen, benötigen Sie mit dieser Funktion nur noch vier Anweisungen (und zusätzlich die Variablen-Deklarationen):

Set objKatalog = CreateSubElement(objXML, "Katalog")
Set objArtikelliste = CreateSubElement(objKatalog, "Artikelliste")
Set objArtikel = CreateSubElement(objArtikelliste, "Artikel")
Set objArtikelname = CreateSubElement(objArtikel, "Artikelname", "Artikelname erster Artikel")

Die Prozedur prüft einfach den Typ des mit objElement übergebenen Objekts (entweder DOMDocument oder IXMLDOMElement) und ordnet das neue Element entsprechend unter. Sollte der Benutzer den optionalen Parameter strText angegeben haben, wird dem soeben erzeugten Objekt auch noch der Text hinzugefügt. Den größten Teil des Dokuments können Sie allein mit den beiden Funktionen AddPi und CreateSubElement erstellen.

Attribut hinzufügen

Das Hinzufügen eines Attributs zu einem Element benötigt nur eine einzige Zeile. Im folgenden Beispiel soll dem Element objArtikel ein Attribut namens ID mit dem Wert des Feldes ArtikelID der Datensatzgruppe rst hinzugefügt werden:

objArtikel.setAttribute "ID", rst!ArtikelID

Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Access im Unternehmen:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 1.000 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein:

Schreibe einen Kommentar