The XMLDOMDocument object exposes properties and methods that allow you to navigate, query, and modify the content and structure of an XML document.
The following topics discuss ways to use the XML Document Object.
Using the XML Document Object Model begins with the creation of the XMLDOMDocument object. Once you have a document object, you can begin to load, parse, navigate, and manipulate XML files.
For JScript developers, a new empty XMLDOMDocument object can be created as follows:
var mydoc = new ActiveXObject("Microsoft.XMLDOM");
For VBScript developers,
Dim xmldoc
Set xmldoc = CreateObject("Microsoft.XMLDOM")
And for Visual Basic programmers,
Dim xmldoc = new DOMDocument
The load method can be used to load an XML file by pathname, URL, or as an IIS Request object. The following example loads an XML file by URL:
XMLDoc.load("http://xmlfiles/reports.xml")
The document object, XMLDoc, now contains a tree consisting of the parsed contents of reports.xml.
You can also load an XML file as a string using the loadXML method.
XMLDoc.loadXML("<customer><first_name>Joe</first_name>
<last_name>Smith</last_name></customer>")
The loading and parsing of an XML file occurs asynchronously by default (you can choose to load the XML file synchronously by setting the async property to false). To abort an asynchronous download, call the abort method on the document object.
You can also assign a new document to a document object by assigning the document a new root element using the documentElement property.
XMLDoc.documentElement = XMLNode
It is important to remember that assigning the document object a new document element does not change the other children of the document. For instance, the doctype element will not change.
To save a parsed XML document to a file or to another object, you can use the save method. The save method takes either a file name as a string, an Active Server Pages (ASP) Response object, an XMLDOMDocument object, or any custom object that supports persistence. The following example is part of an ASP file that saves the XML document to a file.
<%
dim xmldoc
set xmldoc = Server.CreateObject("Microsoft.XMLDOM")
xmldoc.async = false
xmldoc.load(Request)
xmldoc.save(Server.MapPath("sample.xml"))
%>
The XMLDOMDocument object exposes properties that allow the user to change parsing behavior at run time. These four properties are async, validateOnParse, resolveExternals, and preserveWhiteSpace. Each of these properties takes and returns a Boolean value. The default value for async, validateOnParse, and resolveExternals is true; the default value for preserveWhiteSpace is false. The following sample code loads and parses an XML file synchronously; however, the XML document is not validated as it is parsed.
XMLDoc.async = false
XMLDoc.validateOnParse = false
XMLDoc.load("sample.xml")
Note that although not explicitly indicated in the above code, by default the parser will resolve externals and won't honor the value of the xml:space attribute.
Asynchronous parsing allows your application to do other things while the file is being parsed (for example, you may want to display a progress bar). Before you begin to work with the XML document after you load it, be sure to check the readyState property to see if the document has been fully loaded and the DOM is available.
The following properties allow you to get information concerning the document: doctype, implementation, parseError, readyState, and url. You can access these properties to get the document type declaration accompanying the document; the implementation for the document; the last error to occur while parsing; information concerning the state of the XML document; and the URL, if any, of the XML file being loaded and parsed. For more information on error reporting, see the XMLDOMParseError object reference.
The following JScript/HTML example demonstrates the sequence of ready states when asynchronously loading a document:
<script>
var xmldoc;
function Load()
{
xmldoc = new ActiveXObject("Microsoft.XMLDOM");
xmldoc.onreadystatechange = CheckState;
xmldoc.load(URL.value);
}
function CheckState()
{
var state = xmldoc.readyState;
RESULTS.innerHTML += "readyState = " + state + "<BR>"
if (state == 4)
{
var err = xmldoc.parseError;
if (err.errorCode != 0)
RESULTS.innerHTML += err.reason + "<BR>"
else
RESULTS.innerHTML +="success" + "<BR>"
}
}
</script>
URL: <input type=text size=60 id=URL>
<input type=button value=LOAD onclick="jscript:Load()">
<div id=RESULTS style="color:red; font-weight:bold;"></div>
You can access the tree for an XML document either by beginning at the root element and walking down the tree or by querying for a specific node or nodes. You can navigate to the root element of the document through the documentElement property. This property returns the root element as an XMLDOMNode object.
So, for example, with the following XML file (Books.xml):
<COLLECTION>
<BOOK>
<TITLE>Cosmos</TITLE>
<AUTHOR>Carl Sagan</AUTHOR>
<PUBLISHER>Ballantine Books</PUBLISHER>
</BOOK>
<BOOK>
<TITLE>Catwings</TITLE>
<AUTHOR>Ursula K. Le Guin</AUTHOR>
<PUBLISHER>Scholastic</PUBLISHER>
</BOOK>
<BOOK>
<TITLE>Home Town</TITLE>
<AUTHOR>Tracy Kidder</AUTHOR>
<PUBLISHER>Random House</PUBLISHER>
</BOOK>
</COLLECTION>
You can walk the tree this way in VBScript:
Dim root
Dim xmlDoc
Dim child
Set xmlDoc = CreateObject("microsoft.xmldom")
xmlDoc.async = False
xmlDoc.load("c:\books.xml")
'Set root to the XML document's root element, COLLECTION:
Set root = xmlDoc.documentElement
'Walk from the root to each of its child nodes:
For Each child In root.childNodes
MsgBox child.text
Next
When run, the example above displays the text of each of the root's child nodes (BOOK).
You can navigate to a specific node or nodes deep within the tree using either the nodeFromID or getElementsByTagName method. The nodeFromID method takes a unique ID, defined within an XML Schema or Document Type Definition (DTD), and returns the node corresponding to that specific ID (see the Extreme XML column Cross-Reference Your XML Data for more information on how to use IDs and IDREFs). The getElementsByTagName method takes a string representing a specific tag name and returns all the element nodes with this tag name.
Using Books.xml, you can get all of the nodes with the AUTHOR tag with the following code:
Dim ElemList
Dim xmlDoc
Set xmlDoc = CreateObject("microsoft.xmldom")
xmlDoc.async = False
xmlDoc.load("c:\xml\books.xml")
Set ElemList = xmlDoc.getElementsByTagName("AUTHOR")
For i=0 To (ElemList.length -1)
MsgBox ElemList.item(i).xml
Next
Note that the XMLDOMNode object's selectNodes method offers a more flexible way of accessing nodes.
The document object exposes the createNode method, which allows you to create a qualified node by supplying the node type, name, and namespaceURI of the new node.
The document object also exposes the following eight methods defined in the World Wide Web Consortium (W3C) DOM recommendation that allow you to create specific DOM nodes.
The methods that create specific DOM nodes return specific objects and interfaces outlined in the XML DOM Reference. These specific objects and interfaces expose properties and methods associated with that node. For example, the following sample code assigns an XMLDOMElement object with the name of "item" to the variable "xmlElem."
xmlElem = xmlDoc.createElement("item")
You can then add an attribute to that element by calling the setAttribute method and passing that method a string containing the attribute name and a string containing the attribute value.
xmlElem.setAttribute("id","bar")
Using Books.xml again as an example (see Accessing the Document Tree, in Using the XMLDOMDocumentObject topic), the following code creates a new element, PAGES, and uses the appendChild method to add it to the second child node of the root, COLLECTION. It then sets the text property for the new element to "400."
Dim xmlDoc
Dim root
Dim newElem
Set xmlDoc = CreateObject("microsoft.xmldom")
xmlDoc.async = False
xmlDoc.load("c:\books.xml")
Set root = xmlDoc.documentElement
Set newElem = xmlDoc.createElement("PAGES")
root.childNodes.item(1).appendChild newElem
root.childNodes.item(1).lastChild.text = "400"
MsgBox root.childNodes.item(1).xml