Reading XML Files in WSH - Getting started
(Page 2 of 6 )
The first logical step to reading an XML file requires that the file actually be open. To do that, we’re going to create an instance of the XML Document Object Model by instantiating the Microsoft XML Parser. Then we’ll load an XML file.
Set objXmlDoc = CreateObject("Microsoft.XMLDOM")
objXmlDoc.async = False
objXmlDoc.load("C:\Playlist.xml")
This code is pretty straightforward. Notice that I’m setting the XML Document object’s async property to False. XML documents can be loaded either synchronously or asynchronously. In most cases you’ll want to load the file asynchronously. This helps to ensure that the entire file is loaded before script execution continues. If you choose to load the file synchronously, you’ll have to monitor its ReadyState before continuing.
If you want to do some error handling, you can test whether or not the document was successfully loaded by creating an If statement around the load method as follows:
If Not objXmlDoc.load("C:\Playlist.xml") Then
WScript.Echo "Document failed to load."
WScript.Quit
End If
This If statement will produce an error message and halt script execution if the document is not successfully loaded. If you’re having problems getting your document to load, read the “What to do when it doesn’t work” section at the end of this article.
Set objRoot = xmlDoc.documentElement
Now that the file is loaded, you can begin finding the information that you want. Like a database, you’ll most likely know what information you’re looking for; however, you can also use the line above. The documentElement method will effectively return a collection of all of the elements in your document, thus allowing you to traverse them using a For Each structure.
That being so, that’s not where the power of this control lies. As I stated earlier, you can query XML files in the same way you would a standard database. Writing queries will seem a little odd until you try it, but don’t worry; it’s actually quite simple.
Set colNodes = objXmlDoc.selectNodes("/playlist/trackList/*")
The easiest way to query an XML file is by using the XML Document object’s selectNodes method. It accepts a single string parameter as a query and returns a collection of objects that represent matching nodes. In this case, the word node and element can be used interchangeably.
The query here is quite simple. You’re going to create a path-like structure that points to the node level that you wish to return. Here, I want to return all tracks in the playlist. If you look at the XML file again, you can see that the track elements are children of the trackList element, which is a child itself of the playlist element. So a path to a track looks something like this:
<playlist><trackList><track>
The query string presents a path relative to the document root, so we simply name each element in order. You’ll also notice that I’ve used the * wildcard character. This represents all nodes at that level. In other words, I’m returning all nodes that are children of the trackList element.
The * wildcard character is used similarly to a SELECT * FROM query in WMI!
For Each objNode in colNodes
WScript.Echo objNode.Text
Next
As I said, the selectNodes method returns a collection of elements. Thus, you could easily move through the returned elements and display their contents using a For Each loop as I’ve shown above. However, in the case of our example XML file, the track element doesn’t contain any text; it actually contains more elements. So let’s try something a little different.
Set colTracks = objXmlDoc.selectNodes("/playlist/trackList/track/*")
For Each objTrack In colTracks
Set colProperties = objTrack.childNodes
WScript.Echo "Location:", colProperties.Item(0).Text
WScript.Echo "Title:", colProperties.Item(1).Text
WScript.Echo "Creator:", colProperties.Item(2).Text
WScript.Echo ""
Next
In this example, I’m using a query to return all instances of the track element. Then for each of those instances I’m using the childNodes method to return a collection containing the property elements for that particular track. I’m simply echoing back the Text value for each of those property elements.
For Each objTrack In colTracks
Set colProperties = objTrack.childNodes
For Each objProperty In colProperties
WScript.Echo objProperty.baseName & ":", objProperty.Text
WScript.Echo ""
Next
Next
For a quick and easy way of dumping all of the data, you could simply do as I’ve done above. I’m just grabbing all of the property elements with the childNodes method and iterating through them all with a For Each loop. I’ve done this to demonstrate how you can use a node object’s baseName property to return the actual element tag.
Can you see how this might be useful if you want to display an unknown XML file’s document tree?
Next: More advanced queries >>
More Windows Scripting Articles
More By Nilpo