Modifying XML Files in WSH

In my last two articles, I showed you how to create and read XML files in WSH. Today, I’m going to bring this series to a close by showing you how to modify XML files. This includes modifying the text data in the file as well as modifying the XML structure.

Contributed by
Rating: 4 stars4 stars4 stars4 stars4 stars / 5
December 08, 2008
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

To begin, you'll need an XML file to work with. If you don't have the example file from the last two articles, you can grab it here.

Perhaps the most common reason for modifying an XML file is to append data. This is comparable to adding a new record to a database. Let's take our example XSPF playlist and add another set of track information as follows:

location: http://www.nilpo.com/pub/tracks/Crossfade%20-%20Cold.mp3

title: Dead Skin

creator: Crossfade

info: http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?i=187470715%38id=187470617%38s=143441

album: Crossfade

trackNum: 2

The script first needs to open the XML file and load its document tree.

Set objXmlDoc = CreateObject("Microsoft.XMLDOM")

objXmlDoc.async = False

objXmlDoc.load("C:Playlist.xml")

This portion of the script returns an XML Document object by creating an instance of Microsoft's XML Parser. Next, the async property is set to false to help ensure that the script does not continue to execute until the file is fully loaded. Finally, the load method is used to load the XML document into the parser.

Set objRoot = objXmlDoc.documentElement

The XML Document object exposes a documentElement method which has the net effect of returning the first, or root, element of the document. By creating a reference to the root element, you can traverse the entire document tree from the top down. We don't have a need for this in today's example, but it's important to keep this in mind.

Adding new elements

In order to add a new element, we must first create a reference to the new element's parent object. This is most easily done by using a query string. In this case, we need to add a new track element. If you examine the XML file, you will see that track elements are children of the trackList element.

Set objTrackList = objXmlDoc.selectSingleNode("/playlist/trackList")

The selectSingleNode method is used to return a single node based upon the query string provided. In this case, it returns a reference to the trackList element.

Set objTrack = objXmlDoc.createElement("track")

objTrackList.appendChild objTrack

Next, you can use the XML Document object's createElement method to create a new track element. It is then attached to the document as a child of the trackList node by using the appendChild method exposed by that object.

Set objLocation = objXmlDoc.createElement("location")

objLocation.Text = "http://www.nilpo.com/pub/tracks/Crossfade%20-%20Cold.mp3"

objTrack.appendChild objLocation

 

Set objTitle = objXmlDoc.createElement("title")

objTitle.Text = "Dead Skin"

objTrack.appendChild objTitle

 

Set objCreator = objXmlDoc.createElement("creator")

objCreator.Text = "Crossfade"

objTrack.appendChild objCreator

 

Set objInfo = objXmlDoc.createElement("info")

objInfo.Text = "http://phobos.apple.com/WebObjects/MZStore.woa/wa/" _

   & "viewAlbum?i=187470715%38id=187470617%38s=143441"

objTrack.appendChild objInfo

 

Set objAlbum = objXmlDoc.createElement("album")

objAlbum.Text = "Crossfade"

objTrack.appendChild objAlbum

 

Set objTrackNum = objXmlDoc.createElement("trackNum")

objTrackNum.Text = "2"

objTrack.appendChild objTrackNum

Each of the property elements can then be added to the newly created track element in the same manner.  The text property of each newly created child element is set using the text property.

objXmlDoc.save "C:Playlist.xml"

Once you've added all of the required elements, a call to the XML Document object's save method will write those changes to the XML file.

Placing new elements

The previous example demonstrates the simplest approach to adding new records by appending them as children to the existing document tree.  Sometimes, however, you may find that you don't want your newly created element to appear as the last element on the tree. For example, perhaps you wish for it to be the first element.

Set objTrackList = objXmlDoc.selectSingleNode("/playlist/trackList")

Set objFirstChild = objTrackList.firstChild

In this example, I'm taking a slightly different approach. The selectSingleNode method returns a reference to the trackList element. That reference exposes a firstChild method that returns a reference to the object's first child object. In our case, this is the first track element.

Set objTrack = objXmlDoc.createElement("track")

objTrackList.insertBefore objTrack, objFirstChild

Now, we can create a new track element and place it in the document as the first child. To do so, we'll need to use the insertBefore method of the trackList object.  It accepts two parameters: the first is an object reference to the element to be inserted into the document tree and the second is an object reference to the element before which it should be inserted. In this case, the insertBefore method is inserting the newly created track element as a sibling immediately before the first existing track element.

There are several other methods available that can be used to place newly created elements into the document tree as well.

The firstChild method has a counterpart lastChild method. The lastChild method will return a reference to the last child element for an object.

Along with the firstChild and lastChild method, you can also find references to other elements using the previousSibling and nextSibling methods. Just as their names imply, these methods return references to the elements immediately preceding and following an object, respectively. These methods can often be used in conjunction to create the desired affect.

Set objTrackList = objXmlDoc.selectSingleNode("/playlist/trackList")

Set objFirstChild = objTrackList.firstChild

Set objSecondChild = objFirstChild.nextSibling

 

Set objTrack = objXmlDoc.createElement("track")

objTrackList.insertBefore objTrack, objSecondChild

This example will insert the newly created element as the second record. It first uses the firstChild method to return a reference to the first track element. Then, the nextSibling method is used to return a reference to the second track element. Finally, the insertBefore method is used to insert the newly created track element before the second existing one, thus making the new element the second element.

Modifying and deleting existing records

The second most common reason for modifying an XML file is probably to change the data that is stored in it-much like updating a record in a database. There are two distinct approaches you can take when modifying data in an XML file. The first of these is to simply change the text value of an existing element. Take our newly added song for instance. If you look at the links, the song title should have been "Cold," not "Dead Skin."  Let's go ahead and change that now.

Set objTrack = objXmlDoc.selectSingleNode( _

   "/playlist/trackList/track [title = 'Dead Skin']/title")

objTrack.text = "Cold"

Here the selectSingleNode is used to return a reference to the title element of the track record whose title is currently set to "Dead Skin."  That object's text property can then be used to set the title element to a new value. You can also update multiple records at one time.

Set colNodes = objXmlDoc.selectNodes( _

   "/playlist/trackList/track [title = 'Dead Skin']/title")

 

For Each objNode In colNodes

   objNode.Text = "Cold"

Next

In this case, the selectNodes method is used to return a collection of any and all elements matching the criteria. A For Each loop can then be used to modify each matching instance.

Another approach to manipulating the data in an XML file is to replace one element with another. With this method, you can effectively overwrite an element with an updated element. For example, what if we didn't want to add this last song as a new record, but rather wanted to replace an existing song with this one instead?

Set objTrackList = objXmlDoc.selectSingleNode("/playlist/trackList")

 

Set objTrack = objXmlDoc.createElement("track")

objTrackList.replaceChild objTrack, objTrackList.lastChild

This is accomplished using the replaceChild method. The first of its two parameters specifies the newly created object and the second specifies the object that it is to replace. Here, I am simply creating a new track element and replacing the last one in the list.

Finally, you may find that you wish to remove a record (or element) to effectively delete it from the database. Each node object exposes a removeChild method for this. Let's remove the new song that we've just added.

Set objTrack = objXmlDoc.selectSingleNode( _

   "/playlist/trackList/track [title = 'Cold']")

objTrack.parentNode.removeChild objTrack

I've used the selectSingleNode method to return a reference to the track element for the song we've just added to the XML file. In order to remove this element, I must access it from its parent element. Notice how I've used the track object's parentNode method to return a reference to its parent element. Then I've immediately called the removeChild method from the parent and supplied the track object as its parameter. I know that it seems a bit counter-intuitive, but unfortunately, there is no way to remove an element directly.

Set colTracks = objXmlDoc.selectNodes("/playlist/trackList/track")

 

For Each objTrack In colTracks

   objTrack.parentNode.removeChild objTrack

Next

As you probably imagined, you could use this technique for a collection of objects as well. The example above will return every track element and then remove them one by one.

That wraps up this series on working with XML files. Over the course of three articles you've learned how to use the Microsoft XML Parser to create, read, and modify XML files. You'll find the more you use this, the easier it becomes. It's not half as hard as it seems on the surface. Until next time, keep coding!

blog comments powered by Disqus
WINDOWS SCRIPTING ARTICLES

- More Windows Scripting Workarounds from Nilpo
- Overloading Methods and More in VBScript
- Improving MFC for Windows Vista
- Regular Expressions in VBScript
- Working with Dates in WMI
- Completing Calendars with VBScript Date Func...
- Building Calendars with VBScript Date Functi...
- Working With Dates and Times in VBScript
- Designing WCF DataContract Classes Using the...
- Understanding Dates and Times in VBScript
- Working With Arrays in VBScript
- Compressed Folders in WSH
- Using .NET Interops in VBScript
- Nilpo`s Scripting Secrets, Vol I
- Database operations using Silverlight 2.0 WC...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 5 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials