XML Dokumente parsen
XML Dokumente sind hirachisch strukturierte Dokumente die aus einzelnen Knoten bestehen, in denen sich Informationen und weitere Unterknoten befinden können. Um dies zu verdeutlichen habe ich eine einfache Struktur erstellt, eine Bücherliste mit 3 Einträgen:
Um Informationen aus XML Dokumenten per VBA einzulesen bietet sich das DOM-XML an. Genaue Informationen zum DOM-XML findet man z.B. auf dieser MSDN-Seite: http://msdn.microsoft.com/de-de/library/aa468547.aspx
Um die benötigten Objekte zu erstellen benötigt man bei early-Binding einen Verweiss auf die XML Bibliothek. Dazu den Verweis Microsoft XML, v3.0 einbinden. Es gibt auch neuere Versionen dieser Bibliothek, doch die 3.0 genügt vollkommen für diese Zwecke und hat sich bewährt.
Danach kann man das benötigte Objekt deklarieren:
Dim objDomDoc As New DOMDocument
Um auf die Knoten zugreifen zu können benötigt man ein weiteres Objekt:
Dim objNode As IXMLDOMNode
Zuerst wird die XML-Datei geöffnet:
Dim FileName As String Filename = "c:\test\myXMLFile.xml" objDomDoc.async = False objDomDoc.Load Filename
Dann das Objekt für den Wurzel-Knoten gesetzt:
Set objNode = objDomDoc.documentElement
Wie im gezeigten Beispiel-XML zu sehen befinden sich unterhalb dem Wurzel-Knoten (menu) 4 Unterknoten, sogenannte Childnodes (Kindknoten). Der erste heißt „text“, die weiteren drei heißen „menuItem“.
Die Anzahl der Knoten bekommt man über die Eigenschaft objNode.childNodes.length.
Zu beachten ist noch dass die Knoten auf 0 indiziert sind, also der Index der Knoten begint bei 0.
Das erste Buch befindet sich also unter objNode.ChildNode(1), da unter objNode.ChildNode(0) ja der Text steht. Titel, Autor und Verlag erhält man als weiteren Unterknoten, beachtet aber dass der Zähler jetzt bei 0 anfängt. Also 0 für Titel, 1 für Autor und 2 für Verlag. Um aus den Knoten auch die entsprechende Information auszulesen verwendet man die Eigenschaft nodeTypedValue.
Um nun die 3 Bücher auszulesen benötigt man eine For-Schleife:
Dim i As Integer For i = 0 To objNode.childNodes.length - 1 If objNode.childNodes(i).nodeName = "menuItem" Then Titel = objNode.childNodes(i).childNodes(0).nodeTypedValue Autor = objNode.childNodes(i).childNodes(1).nodeTypedValue Verlag = objNode.childNodes(i).childNodes(2).nodeTypedValue End If Next i
Die For-Schleife beginnt bei 0 da der Index bei 0 beginnt, am Schluss -1 weil von 0 bis 4 bekanntlich 5 Elemente sind, wir haben in unserem Beispiel aber nur 4 Elemente (Knoten unterhalb des Wurzelknotens).
Wenn man viele Hirachien im Dokument hat kann man auch anstatt des Wurzelknotens ein bestimmter Unterknoten definieren. In unserem Beispiel könnte man z.B. auch dieses schreiben:
Dim Buch1 As IXMLDOMNode Set Buch1 = objDomDoc.documentElement.childNodes(1) Titel = Buch1.childNodes(0).nodeTypedValue
Abschließend ein komplettes Beispiel zum XMLImport:
Sub XMLImport() Dim objDomDoc As New DOMDocument Dim objNode As IXMLDOMNode Dim objChildNode As IXMLDOMNode Dim Filename As String Dim Titel As String Dim Autor As String Dim Verlag As String Dim SQL As String Dim db As DAO.Database On Error GoTo Fehler Set db = CurrentDb Filename = "C:\Test\testxml1.xml" objDomDoc.async = False objDomDoc.Load Filename ' das Wurzelknoten-Objekt erstellen Set objNode = objDomDoc.documentElement For i = 0 To objNode.childNodes.length - 1 ' Auslesen nur wenn der Unterknoten-Name menuItem ist If objNode.childNodes(i).nodeName = "menuItem" Then Titel = Nz(objNode.childNodes(i).childNodes(0).nodeTypedValue, "") Autor = Nz(objNode.childNodes(i).childNodes(1).nodeTypedValue, "") Verlag = Nz(objNode.childNodes(i).childNodes(2).nodeTypedValue, "") ' SQL-String für Einfügeabfrage zusammenstellen SQL = "Insert into Tabelle1 (Titel, Autor, Verlag) Values " & _ "('" & Titel & "', '" & Autor & "', '" & Verlag & "')" ' SQL-String wegschreiben db.Execute SQL End If Next i MsgBox "Import beendet!" Exit_Fehler: Exit Sub Fehler: MsgBox Err.Description Resume Exit_Fehler End Sub
AV 2009
Inzwischen gibt es das DOMDocument60, eine Verbesserung gegenüber früheren Versionen vorallem in Punkto Sicherheit wurde was getan. Als Verweiss sollte Microsoft XML 6.0 verwendet werden. An der eigentlichen Programmierung – außer dass das Objekt etwas anderst heißt – hat sich nichts geändert.
Gruß Andreas Vogt