Wir haben nun in einigen Artikeln beschrieben, welche Möglichkeiten die Bordmittel von Access für das Lesen und Schreiben von XML-Dokumenten bieten. Richtig flexibel ist das ganze natürlich nicht beziehungsweise nur, wenn Sie mit XSL nachhelfen. Wenn es beim Einlesen von XML-Dokumenten richtig individuell werden soll, können Sie aber immer noch mit VBA arbeiten. Dazu benötigen Sie nur einen Verweis auf die Objektbibliothek mit den Befehlen zum Bearbeiten von XML-Dokumenten – und das Know-how aus diesem Artikel.
Beispieldatenbank
Die Beispiele dieses Artikels finden Sie in der Datenbank 1904_XMLLesenVBA.accdb.
Voraussetzungen
Um per VBA auf XML-Dokumente zuzugreifen, brauchen Sie imgrunde noch nicht einmal eine spezielle Bibliothek. XML-Dokumente sind ja auch nichts anderes als einfache Textdateien, nur das ihre Inhalte durch die XML-Auszeichnungen auf bestimmte Art strukturiert sind.
Im Notfall können Sie sich also auch mit der Open-Anweisung und den Zeichenkettenfunktionen von VBA behelfen. Aber wir wollen es natürlich schon etwas komfortabler haben und nutzen daher die Bibliothek Microsoft XML, 6.0.
Diese fügen Sie im VBA-Editor über den Menüeintrag Extras|Verweise und den dann erscheinenden Dialog Verweise wie in Bild 1 hinzu.
Bild 1: Verweis auf die XML-Bibliothek
Wenn Sie nun mit der Schaltfläche F2 den Objektkatalog öffnen, können Sie nach der Auswahl des Eintrags MSXML2 oben im Kombinationsfeld alle Elemente dieser Bibliothek einsehen (siehe Bild 2).
Bild 2: Objektkatalog von VBA
Beispieldokument
Wir wollen die Daten aus einem XML-Dokument mit einer Bestellung als Beispiel verwenden, das Sie auch auf der folgenden Microsoftseite finden können – für den Fall, dass Sie mit weiteren Beispieldokumenten experimentieren wollen:
https://docs.microsoft.com/de-de/dotnet/visual-basic/programming-guide/concepts/linq/sample-xml-documents-linq-to-xml
Das Dokument sieht wie in Listing 1 aus. Es enthält genau eine Bestellung, die im Element PurchaseOrder enthalten ist. Das Hauptelement enthält in zwei Attributen die Bestellnummer und das Bestelldatum.
<xml version="1.0"> <PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20"> <Address Type="Shipping"> <Name>Ellen Adams</Name> <Street>123 Maple Street</Street> <City>Mill Valley</City> <State>CA</State> <Zip>10999</Zip> <Country>USA</Country> </Address> <Address Type="Billing"> <Name>Tai Yee</Name> <Street>8 Oak Avenue</Street> <City>Old Town</City> <State>PA</State> <Zip>95819</Zip> <Country>USA</Country> </Address> <DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes> <Items> <Item PartNumber="872-AA"> <ProductName>Lawnmower</ProductName> <Quantity>1</Quantity> <USPrice>148.95</USPrice> <Comment>Confirm this is electric</Comment> </Item> <Item PartNumber="926-AA"> <ProductName>Baby Monitor</ProductName> <Quantity>2</Quantity> <USPrice>39.98</USPrice> <ShipDate>1999-05-21</ShipDate> </Item> </Items>
Listing 1: Inhalt eines XML-Dokuments mit einer Bestellung
Darunter finden Sie die Liefer- und die Rechnungsadresse jeweils in Address-Elementen mit entsprechenden Unterelementen.
Ob es sich um eine Liefer- oder Bestelladresse handelt, entnehmen Sie dem Attribut Type des Address-Elements.
Darunter folgen DeliveryNotes als eigenes Element sowie eine Auflistung namens Items mit einigen Item-Elementen, welche die eigentlichen Bestellpositionen ausmachen. In den folgenden Abschnitten zeigen wir, wie Sie die dort enthaltenen Informationen per VBA und mithilfe der XML-Bibliothek auslesen können.
Die DOMDocument-Klasse
Um auf den Inhalt eines Dokuments zuzugreifen, wollen wir dieses zunächst referenzieren. Dazu gibt es genau eine geeignete Klasse, nämlich DOMDocument60.
Diese deklarieren wir mit der Variablen objXML, danach instanzieren wir ein neues Objekt auf Basis dieser Klasse mit dem New-Schlüsselwort.
Die DOMDocument-Klasse bietet unter anderem die beiden Methoden Load und LoadXML an:
- Load: Erwartet die Angabe des Pfades zum einzulesenden XML-Dokument als Parameter und liefert den Wert True zurück, wenn das Einlesen erfolgreich war.
- LoadXML: Erwartet ein XML-Dokument in Form einer Zeichenkette als Parameter. Auch hier liefert der Rückgabewert die Information, ob das Einlesen erfolgreich war.
Mit unserer Beispieldatei PurchaseOrder.xml sieht das Einlesen wie in der folgenden Prozedur aus. Hier prüfen wir direkt, ob das Einlesen erfolgreich war. Falls ja, geben wir den Inhalt des Dokuments im Direktbereich des VBA-Editors aus. Dazu verwenden wir die Debug.Print-Anweisung mit der XML-Eigenschaft von objXML.
Public Sub DokumentReferenzieren() Dim objXML As DOMDocument60 Set objXML = New DOMDocument60 If objXML.Load(CurrentProject.Path _ & "\PurchaseOrder.xml") = True Then Debug.Print objXML.XML Else MsgBox "Fehler beim Einlesen" End If End Sub
Fehler beim Einlesen
In unserem Beispiel gibt es keine Probleme beim Einlesen. Was aber könnte dabei nicht funktionieren Es kann zum Beispiel vorkommen, dass das XML-Dokument nicht wohlgeformt ist.
Das bedeutet, dass zum Beispiel das öffnende Element
Um herauszufinden, welcher Fehler vorliegt, können Sie die Eigenschaften des Elements ParseError nutzen. Dazu fügen wir dem Else-Teil der If…Then-Bedingung aus der obigen Prozedur noch ein paar weitere Zeilen hinzu:
Debug.Print "Fehler bei Einlesen:" Debug.Print "ErrorCode: " & objXML.parseError.errorCode Debug.Print "Filepos: " & objXML.parseError.filepos Debug.Print "Line: " & objXML.parseError.Line Debug.Print "LinePos: " & objXML.parseError.linepos Debug.Print "Reason: " & objXML.parseError.reason Debug.Print "srcText: " & objXML.parseError.srcText Debug.Print "Url: " & objXML.parseError.url
Wenn wir einmal das schließende PurchaseOrder-Element aus dem Dokument entfernen und die Prozedur erneut aufrufen, erhalten wir die Informationen aus Bild 3.
Bild 3: Fehlerinformationen des parseError-Objekts
Die Meldung, welche die Eigenschaft Reason für uns bereithält, ist aussagekräftig genug, um den Fehler zu beheben.
Das Root-Element einlesen
Unser objXML-Objekt enthält nach dem Aufruf der Load-Methode, wie wir der XML-Eigenschaft entnehmen konnten, den kompletten Inhalt des XML-Dokuments. Wie können wir auf die einzelnen Elemente des Dokuments zugreifen und deren Inhalt ausgeben Als Erstes wollen wir dabei das sogenannte Root-Element referenzieren, das in unserem Fall so aussieht:
...
Um auf ein einzelnes XML-Element innerhalb eines Dokuments zu verweisen, benötigen wir eine Objektvariable mit dem passenden Typ, in diesem Fall IXMLDOMElement:
Public Sub RootElementReferenzieren() Dim objXML As DOMDocument60 Dim objRoot As IXMLDOMElement Set objXML = New DOMDocument60
Nach dem Laden des documentElement-Elements referenzieren wir das Root-Element dann über die document-Element-Eigenschaft:
objXML.Load CurrentProject.Path & "\PurchaseOrder.xml"
Set objRoot = objXML.documentElement
Danach können wir beispielsweise mit baseName den Namen des Elements ermitteln, hier PurchaseOrder, oder mit der XML-Eigenschaft den Inhalt des XML-Elements ausgeben:
Debug.Print objRoot.baseName Debug.Print objRoot.XML End Sub
Möchten Sie weiterlesen? Dann lösen Sie Ihr Ticket!
Hier geht es zur Bestellung des Jahresabonnements des Magazins Access [basics]:
Zur Bestellung ...
Danach greifen Sie sofort auf alle rund 400 Artikel unseres Angebots zu - auch auf diesen hier!
Oder haben Sie bereits Zugangsdaten? Dann loggen Sie sich gleich hier ein: