Internet Explorer 5 s Implementation of the XML DOM

[Previous] [Next]

The implementation of the XML DOM in Internet Explorer 5 consists of a set of objects that can be used to load an XML document. Once the document is loaded, you can parse, navigate, and manipulate the information in the XML document. The DOM can also be used for retrieving information about the document.

There are four main objects included with Internet Explorer 5's implementation of the XML DOM: XMLDOMDocument, XMLDOMNode, XMLDOMNodeList, and XMLDOMNamedNodeMap. In addition, sixteen other objects are part of Internet Explorer 5's implementation of the XML DOM. All of these objects have properties and methods that you can use to gather information about the document (including its structure) and to navigate to other object nodes within a document tree. A node is a reference to any object that can exist in a document hierarchy. The ability to access different nodes of the document tree is a function that is also available using XPath and XPointer. Twelve different types of nodes are available in the DOM: element, attribute, text, CDATA section, entity reference, entity, processing instruction, comment, document, document type, document fragment, and notation. An interface exists for each of these node types that allows you to gather and manipulate information on the node. The most common node types are the element, attribute, and text nodes.

NOTE
Attributes are not actually child elements of any node in the tree, so they have a special programming interface called IXMLDOMNamedNodeMap.

The W3C DOM specification defines two types of programming interfaces: fundamental and extended. The fundamental DOM interfaces are required when writing applications that manipulate XML documents. The extended interfaces are not required, but make it easier for developers to write applications. The Internet Explorer 5 DOM implements both the fundamental and extended interfaces. In addition, it provides other interfaces to support Extensible Stylesheet Language (XSL), XSL patterns, namespaces, and data types.

For script developers, the most important object in the Internet Explorer 5's implementation of the XML DOM is the XMLDOMDocument object, which allows developers to navigate, query, and modify the content and structure of an XML document. This object implements the IXMLDOMDocument interface. We will look at this object first.

XMLDOMDocument Object

To navigate and get a reference to an XML document, you need to use the XMLDOMDocument object. Once you actually get a reference to the document, you can begin to work with it. The XMLDOMDocument object implements the IXMLDOMDocument interface.

Getting a reference to an XML document

Depending on the programming language you are using, you can get a reference to an XML document in several ways.

In Microsoft JScript, you can get a reference as follows:

 var objXMLdoc = new ActiveXObject("Microsoft.XMLDOM); objXMLdoc.load("http://www.northwindtraders.com/sales.xml"); 

In VBScript, the code for obtaining a reference appears as follows:

 Dim objXMLdoc Set objXMLdoc = CreateObject("Microsoft.XMLDOM") objXMLdoc.load("http://www.northwindtraders.com/sales.xml") 

In Microsoft Visual Basic, you should add a reference to Msxml.dll to your project by choosing References from the Project menu, and then choosing Microsoft XML version 2 from the References dialog box. The code to get a reference to an XML document appears as follows:

 Dim objXMLdoc As DomDocument Set objXMLdoc = New DomDocument objXMLdoc.load("http://www.northwindtraders.com/Sales.xml") 

You could also use the following code without setting the reference, though the above method is preferable:

 Set objXMLdoc = CreateObject("Microsoft.XMLDOM") objXMLdoc.load("http://www.northwindtraders.com/Sales.xml") 

IXMLDOMDocument interface properties and methods

In the above examples, we used the load method to get a reference to an actual XML document. The following tables list the properties, methods, and events associated with the IXMLDOMDocument interface. Properties and methods that are extensions of the W3C DOM Level 1 specification will be marked with an asterisk (*) throughout this chapter.

NOTE
Code samples illustrating how to use the IXMLDOMDocument interface will be presented later in this chapter.

IXMLDOMDocument Properties

NameDescription
async* Downloads the XML document asynchronously if this property is set to true (the default).
attributes Returns an XMLDOMNamedNodeMap object for nodes that can return attributes.
baseName* Returns the name of the node with any namespace removed.
childNodes Returns all children of the current node for nodes that are allowed children.
dataType* Sets or returns the data type for an XML document node that uses a schema. For entity references, elements, and attributes, if a data type is specified in the schema it will return the data type as a string. If no value is specified, it returns null, and for all other nodes it returns string. Attempts to set the dataType property for nodes other than attribute, element, or entity reference are ignored.
definition* Returns the node that contains the DTD or schema definition for the entity referenced.
doctype Returns a reference to an XMLDOMDocumentType node containing a reference to the DTD or schema.
documentElement Returns a reference to the outermost document element of an XML document.
firstChild Returns a reference to the first child of the current node.
implementation Returns a reference to the XMLDOMImplementation object for the document.
lastChild Returns a reference to the last child node of the current node.
namespaceURI* Returns the Uniform Resource Identifier (URI) for the namespace as a string.
nextSibling Returns a reference to the next sibling node of the current node.
nodeName Returns the name of the node.
nodeTypeString* Returns the node type as a string.
nodeType Returns the node type as a number.
nodeTypedValue* Returns or sets the strongly typed value of the node.
nodeValue Sets or returns the value of the node as text. Returns attribute value for attribute nodes. Returns the text within the CDATA section for CDATASection nodes. Returns the comment for comment nodes. Returns the processing instruction for processing instruction nodes. Returns the text for text nodes. For all other nodes, it returns null if you try to get the property and raises an error if you try to set the property.
ownerDocument Returns the root of the document that contains this node.
parentNode Returns the parent node of the current node for nodes that are allowed to have parents.
parsed* Returns true if the current node and all of its descendants have been parsed and instantiated.
parseError* Returns a reference to the XMLDOMParseError object that contains information about the last parsing error.
prefix* Returns the element namespace prefix as a string.
preserveWhiteSpace* Specifies if white space should be preserved. The default is false.
previousSibling Returns a reference to the previous sibling node of the current node.
readyState* Indicates the current state of an XML document.
resolveExternals* Resolves the external entities, and the document is resolved against external DTDs, if this is true. The default is false.
specified* Returns true if a node value is specified. Returns false if a node value is derived from a default value. (This is normally used only with attribute nodes.)
text* Sets and returns the text content of the current node and all of its descendants.
url* Returns the URL of the last successfully loaded XML document or returns null if the XML document was built in memory.
validateOnParse* The document will validate on parsing when this property is set to true, but the parser will only check the document for being well formed if this property is set to false. Default is true. This property can be set or read.
xml* Returns the entire XML content of the current node and all of its descendant nodes.

IXMLDOMDocument Methods

NameDescription
abort()* Stops the asynchronous load if the async property is set to true and the document is loading. Any information that has been downloaded is discarded. If the readyState property is equal to COMPLETED, calling abort has no effect.
appendChild (newChild) Appends newChild to the end of the child nodes list for the currently selected node.
cloneNode (deep) Creates a clone node that is identical to the currently referenced node. If deep is set to true, all child nodes are also cloned.
createAttribute (name) Creates an attribute node with the specified name.
createCDATASection (text) Creates a CDATASection node containing text.
createComment (text) Creates a comment node containing text. The comment delimiters (<!-- -->) will be inserted.
createDocumentFragment() Creates an empty DocumentFragment node that is used to build independent sections of the XML document.
createElement (name) Creates an instance of the specified element.
createEntityReference (name) Creates an EntityReference node called name.
createNode (type, name, namespace)* Creates any type of node using the specified type, name, and namespace parameters.
createProcessingInstruction (target, data) Creates a new processing instruction. The target parameter provides both the target and the node name. The data parameter is the actual instruction.
createTextNode (text) Creates a text node containing the text specified in the text parameter.
getElementsByTagName (name) Returns a collection of child elements that have the specified tag name. If the name parameter is *, it returns all elements.
hasChildNodes() Returns true if the node has any child nodes.
insertBefore (newNode, beforeNode) Inserts a new node object called newNode into the list of child nodes for the current node to the left of the beforeNode or at the end if beforeNode is left out.
load (url)* Loads an XML document from the specified URL.
loadXML (string)* Loads a string that contains well-formed XML.
nodeFromID (value)* Returns the node object that has an ID attribute matching the supplied value.
removeChild (node) Removes the child node from the current node and returns it.
replaceChild (newNode, oldNode) Replaces the child node oldNode with the node newNode.
save (destination)* Saves the file to the specified destination.
selectNodes (pattern)* Returns a node list object containing matching nodes. The pattern parameter is a string containing an XSL pattern.
selectSingleNode (pattern)* Returns the first node object matching the pattern of a string containing XSL.
transformNode (stylesheet)* Processes the node and its children using XSL pattern matching. The stylesheet parameter must be either an XMLDOMDocument node object or a node object in the XSL namespace.
transformNodeToObject (stylesheet, outputobject) Transforms the node according to the XSL document and places the transformed document into the outputobject parameter.

IXMLDOMDocument Events

NameDescription
ondataavailable* Occurs whenever data becomes available. When the async property is true, this event fires several times as data comes in. Using the readyState property, you can obtain information on the incoming data, including when all of the data has been downloaded.
onreadystatechange* Fires whenever the readyState property changes.
ontransformnode* Fires when a node is transformed using the TransformNode method of the node object.

XMLDOMNode Object

The XMLDOMNode object implements the IXMLDOMNode interface. This interface contains the following properties: attributes, baseName, childNodes, dataType, definition, firstChild, lastChild, namespaceURI, nextSibling, nodeName, nodeTypeString , nodeType, nodeTypedValue, nodeValue, ownerDocument, parentNode, parsed, prefix, previousSibling, specified, text, and xml. The methods associated with IXMLDOMNode are appendChild, clonenode, hasChildNodes, insertBefore, removeChild, replaceChild, selectNodes, selectSingleNode, transformNode, and transformNodeToObject. There are no events associated with the IXMLDOMNode interface.

Looking at these properties and methods, you can see that they're all included in the IXMLDOMDocument interface and have been defined above. The same methods exist in both interfaces because IXMLDOMNode is used as the base interface for building all W3C DOM objects except for IXMLDOMImplementation, IXMLDOMNodeList, and IXMLDOMNamedNodeMap, as illustrated in Figure 11-1.

Besides these interfaces, Internet Explorer 5 has three additional interfaces: IXTLRuntime, IXMLDOMParseError, and IXMLHTTPRequest. You can see all the interfaces, including those specific to Internet Explorer 5, in Figure 11-2.

click to view at full size.

Figure 11-1. The relationship between the W3C DOM object interfaces.

click to view at full size.

Figure 11-2. Internet Explorer 5 DOM interfaces.

Let's look at how to code some of the methods and properties that belong to the IXMLDOMNode interface.

NOTE
The following example will show you how to use some of the properties and methods of the IXMLDOMNode interface using Visual Basic. If you have access to Visual Basic, I highly recommend that you follow the examples. If you don't have Visual Basic, you can easily convert this example to a script sample. This example will print out the values of various properties to the Immediate Window.

To create the sample application, follow these steps:

  1. Open Visual Basic, create a standard EXE project, and change the name of the default form to frmDOMTest.
  2. Choose References from the Project menu, and add a reference to Microsoft XML, version 2.0.
  3. Add a command button to frmDOMTest called cmdNode with a caption Nodes.
  4. Add the following code to the click event handler of cmdNode:
  5.  Private Sub cmdNode_Click() Dim objXMLDoc As DOMDocument 'Create a node object that is a reference to the root object. Dim objRoot As IXMLDOMNode 'Create a node object that can be used to create a new node. Dim objNewNode As IXMLDOMNode Set objXMLDoc = New DOMDocument 'Turn off asynchronous load as we do not need it for this example. objXMLDoc.async = False 'Open the file shown below. objXMLDoc.Load ("c:\Books.xml") 'The documentElement will return the root element. Set objRoot = objXMLDoc.documentElement 'Begin printing out properties for the root. Debug.Print "XML for the root: " & vbCrLf & objRoot.xml Debug.Print "BaseName for the root: " & objRoot.baseName Debug.Print "Namespace prefix for the root: " & objRoot.prefix Debug.Print "DataType for the root: " & objRoot.dataType 'We will begin to walk through the document starting at the first 'child. Debug.Print "First Child XML for the root: " & vbCrLf & _ objRoot.firstChild.xml 'We will get the next child, which is two elements down from 'the root. Debug.Print "First Child of Child XML for the root: " & _ objRoot.firstChild.firstChild.xml 'Nextsibling will return a node on the same level, in this case 'the same level as the second element down from the root. Debug.Print "Second Child of Child XML for the root: " & _ objRoot.firstChild.firstChild.nextSibling.xml Debug.Print "Third Child of Child XML for the root: " & _ objRoot.firstChild.firstChild.nextSibling. _ nextSibling.xml Debug.Print "Fourth Child of Child XML for the root: " & _ objRoot.firstChild.firstChild.nextSibling. _ nextSibling.nextSibling.xml Debug.Print "Namespace URI for the root: " & _ objRoot.namespaceURI Debug.Print "Nodename for the root: " & objRoot.nodeName Debug.Print "NodeType for the root: " & objRoot.nodeType Debug.Print "NodeType String for the root: " & _ objRoot.nodeTypeString Debug.Print "NodeValue for the root: " & objRoot.nodeValue Debug.Print "parentNode for the root: " & _ objRoot.parentNode.xml 'Using XSL to get a single node Debug.Print "XSL selecting first child node of the item node: " & _ vbCrLf & objRoot.selectSingleNode("item/*").xml Set objNewNode = objXMLDoc.createNode(1, "test", "") objRoot.appendChild objNewNode Debug.Print "Root XML after appending: " & vbCrLf & objRoot.xml Set objNewNode = Nothing Set objRoot = Nothing Set objXMLDoc = Nothing End Sub 

Notice that we first get a reference to the document object. Using this reference, we can get a reference to the XMLDOMNode object. Then we start navigating the nodes in the XML document. Finally, we create a node named test and append it as a child node to the root node. To test this application, let's create an XML document called Books.xml in the C:\ directory with the following XML:

 <?xml version="1.0" ?> <northwind:BOOKS xmlns:northwind="www.northwindtraders.com/PO"> <item> <title>Number, the Language of Science</title> <author>Danzig</author> <price>5.95</price> <quantity>3</quantity> </item> </northwind:BOOKS> 

When you run the program and click the Nodes button, the results are as follows:

 XML for the root: <northwind:BOOKS xmlns:acme="www.northwindtraders.com/PO"> <item> <title>Number, the Language of Science</title> <author>Danzig</author> <price>5.95</price> <quantity>3</quantity> </item> </northwind:BOOKS> BaseName for the root:BOOKS Namespace prefix for the root:northwind DataType for the root: First Child XML for the root: <item> <title>Number, the Language of Science</title> <author>Danzig</author> <price>5.95</price> <quantity>3</quantity> </item> First Child of Child XML for the root: <title>Number, the Language of Science</title> Second Child of Child XML for the root: <author>Danzig</author> Third Child of Child XML for the root: <price>5.95</price> Fourth Child of Child XML for the root: <quantity>3</quantity> Namespace URI for the root: www.northwindtraders.com/PO Nodename for the root: northwind:BOOKS NodeType for the root: 1 NodeType String for the root: element NodeValue for the root: parentNode for the root: <?xml version="1.0"?> <northwind:BOOKS xmlns:northwind="www.northwindtraders.com/PO"> <item> <title>Number, the Language of Science</title> <author>Danzig</author> <price>5.95</price> <quantity>3</quantity> </item> </northwind:BOOKS> XSL selecting first child node of ITEM: <title>Number, the Language of Science</title> Root XML after appending: <northwind:BOOKS xmlns:northwind="www.northwindtraders.com/PO"> <item> <title>Number, the Language of Science</title> <author>Danzig</author> <price>5.95</price> <quantity>3</quantity> </item> <test/></northwind:BOOKS> 

Notice that the test element was inserted as the last child of the root, which is what we would have expected. Once this element is inserted, you can add text values or make other changes. All the sample programs discussed in this chapter, including the Visual Basic sample program and Books.xml, are available on the companion CD.

NOTE
Though we have not discussed XSL yet, we used XSL to get a single node in the previous application. XSL defines the location of elements using the XPath syntax. We'll discuss XSL in detail in Chapter 12. In this chapter, we will use the XPath syntax with the selectSingleNode method.

Several methods and properties belonging to the document object will return other objects in the hierarchy, such as selectNodes or attributes. We'll discuss these methods and properties while examining other object interfaces in the XML DOM.

XMLDOMNodeList Object

The XMLDOMNodeList object is a collection of node objects. It is primarily used to iterate through the element nodes. This object implements the IXMLDOMNodeList interface. The IXMLDOMNodeList interface reflects the current state of the nodes in the document, so a change in the nodes will be immediately reflected in the object. The property and methods of IXMLDOMNodeList are as follows:

IXMLDOMNodeList Property

NameDescription
lengthReturns the number of nodes that are contained in the node list.

IXMLDOMNodeList Methods

NameDescription
item (index) Returns the node located at position index in the node list. The first node is indexed as 0.
nextNode()* Returns the next node object in the node list. If there are no more nodes, it returns null.
reset()* Resets the pointer so that it points before the first node element.

For an example of the IXMLDOMNodeList interface, you can add an attribute to the XML document and another command button to the frmDOMTest form. To do so, follow these steps:

  1. Open the XML document Books.xml and change the title element to the following:
  2.  <title language="English">Number, the Language of Science </title> 

  3. Add another command button to the frmDOMTest form called cmdNodeList with the caption NodeList.
  4. Add the following code to the click event handler of the cmdNodeList button:
  5.  Private Sub cmdNodeList_Click() Dim objNodeList As IXMLDOMNodeList Dim objXMLDoc As DOMDocument Set objXMLDoc = New DOMDocument objXMLDoc.async = False objXMLDoc.Load ("c:\Books.xml") Set objNodeList = _ objXMLDoc.documentElement.firstChild.childNodes Debug.Print "The second item's basename is: " & _ objNodeList.Item(2).baseName Debug.Print "The number of nodes are: " & objNodeList.length Debug.Print "The first node xml is: " & vbCrLf & _ objNodeList.nextNode.xml Debug.Print "The second node xml is: " & _ objNodeList.nextNode.xml Debug.Print "The third node xml is: " & _ objNodeList.nextNode.xml objNodeList.Reset Debug.Print "After reset, the first node xml is: " & _ vbCrLf & objNodeList.nextNode.xml Dim intNodeCounter As Integer For intNodeCounter = 0 To objNodeList.length - 1 Debug.Print "The " & "xml of node" & _ Str(intNodeCounter + 1) & " is: " & vbCrLf & _ objNodeList.Item(intNodeCounter).xml Next Set objNodeList = Nothing Set objXMLDoc = Nothing End Sub 

Notice that, once again, we first get a reference to the document object. Once we have this reference, we can get a reference to the IXMLDOMNodeList interface. Then we use the item, nextNode, and reset methods of the IXMLDOMNodeList interface to navigate the document. Last, we print all the nodes in the collection with a loop. When you run this updated application and click the NodeList button, the results are as follows:

 The second item's basename is: price The number of nodes are: 4 The first node xml is: <title language="English">Number, the Language of Science</title> The second node xml is: <author>Danzig</author> The third node xml is: <price>5.95</price> After reset, the first node xml is: <title language="English">Number, the Language of Science</title> The xml of node 1 is: <title language="English">Number, the Language of Science</title> The xml of node 2 is: <author>Danzig</author> The xml of node 3 is: <price>5.95</price> The xml of node 4 is: <quantity>3</quantity> 

Notice that the attribute node was not included in the results. We will need to use the IXMLDOMNamedNodeMap interface to get a reference to attribute nodes.

XMLDOMNamedNodeMap Object

The XMLDOMNamedNodeMap object implements the IXMLDOMNamedNodeMap interface. This interface is similar to the IXMLDOMNodeList interface except that it allows you to iterate through attributes and namespace nodes. The IXMLDOMNamedNodeMap interface has the same length property as the IXMLDOMNodeList interface. IXMLDOMNamedNodeMap also has the same item, nextNode, and reset methods as the IXMLDOMNodeList interface. The additional methods that are associated with the IXMLDOMNamedNodeMap are as follows:

Additional IXMLDOMNamedNodeMap Methods

NameDescription
getNamedItem (name) Retrieves the node object with the specified name. This method is usually used to retrieve an attribute from an element.
getQualifiedItem (baseName, namespace)* Returns the node object with the specified baseName and namespace.
removeNamedItem (name) Removes the node object that has the specified name from the named node map. This method is usually used to remove an attribute.
removeQualifiedItem (baseName, namespace)* Removes the node object with the specified baseName and namespace. This method is usually used to remove attributes from the collection.
setNamedItem (newNode) Inserts a new node into the collection. If a node with the same name as the newNode already exists, it's replaced.

To illustrate how to use the methods and properties of IXMLDOMNamedNodeMap, add another command button to the frmDOMTest form with the name cmdNamedNodeMap and the caption NamedNodeMap. Add the following code to the click event handler of the cmdNamedNodeMap button:

 Private Sub cmdNamedNodeMap_Click() Dim objNamedNodeMap As IXMLDOMNamedNodeMap Dim objXMLDoc As DOMDocument Set objXMLDoc = New DOMDocument objXMLDoc.async = False objXMLDoc.Load ("c:\Books.xml") Set objNamedNodeMap = objXMLDoc.documentElement.Attributes Debug.Print _ "The root's first attribute node's basename is: " & _ objNamedNodeMap.Item(0).baseName Debug.Print "The number of root's attribute nodes is: " & _ objNamedNodeMap.length Debug.Print "The first node xml is: " & _ objNamedNodeMap.nextNode.xml Set objNamedNodeMap = _ objXMLDoc.documentElement.firstChild.firstChild.Attributes Debug.Print _ "The title element's attribute node's" & _ " basename is: " & objNamedNodeMap.Item(0).baseName Debug.Print "The number of the title element's " & _ "attribute nodes is: " & objNamedNodeMap.length Set objNamedNodeMap = Nothing Set objXMLDoc = Nothing End Sub 

Once again, to move through the XML document you will begin by getting a reference to a document object. This time, you will use the attributes property of the document object to get a reference to the IXMLDOMNamedNodeMap interface. When you run this example and click the NamedNodeMap button, the results are as follows:

 The root's first attribute node's basename is: northwind The number of the root's attribute nodes is: 1 The first node xml is:xmlns: northwind="www.northwindtraders.com/PO" The title element's attribute node's baseName is: language The number of the title element's attribute nodes is: 1 

Thus, using the IXMLDOMDocument interface's attributes property and the IXMLDOMNamedNodeMap interface we are able to get information about the namespace and attribute nodes.

XMLDOMDocumentType Object

The XMLDOMDocumentType object implements IXMLDOMDocumentType interface. The doctype property of the IXMLDOMDocument interface identifies the document's IXMLDOMDocumentType interface. The IXMLDOMDocumentType interface gets information on the document type declaration in the XML document. This interface also extends the IXMLDOMNode interface, so it has all the properties and methods of the IXMLDOMNode interface. The IXMLDOMDocumentType interface also implements the following extended properties:

Additional IXMLDOMDocumentType Properties

NameDescription
entities Returns a node list containing references to the entity objects declared in the DTD
name Returns the name of the document type for the document
notations Returns a node list containing references to the notation objects in the DTD

Now that the IXMLDOMDocumentType interface contains information associated with the DTD, let's create a DTD named Books.dtd for the document using the following text:

 <!ELEMENT northwind:BOOKS (item)> <!ATTLIST northwind:BOOKS xmlns:northwind CDATA #FIXED "www.northwindtraders.com/PO"> <!ENTITY % ItemElements "(title, author, price, quantity)"> <!ENTITY copyright "&#xA9;"> <!ELEMENT item %ItemElements;> <!ELEMENT title (#PCDATA)> <!ATTLIST title language CDATA #REQUIRED> <!ELEMENT author (#PCDATA)> <!ELEMENT price (#PCDATA)> <!ELEMENT quantity (#PCDATA)> 

Notice that we declared a general entity called copyright in the above DTD, thus we need to reference this entity in the Books.xml document. We also need to add a line of code to the XML document so that it will reference the DTD:

 <?xml version="1.0" ?> <!DOCTYPE northwind:BOOKS SYSTEM "c:\Books.dtd"> <northwind:BOOKS xmlns:northwind="www.northwindtraders.com/PO"> <item> <title language="English">Number, the Language of Science &copyright; </title> <author>Danzig</author> <price>5.95</price> <quantity>3</quantity> </item> </northwind:BOOKS> 

NOTE
Remember that the DTD has no ability to resolve namespaces. Thus, you must declare the elements that use the namespace with the namespace prefix and define an attribute for the namespace. The XML document, though, can resolve the namespace information.

Now let's take a look at how to use the properties of the IXMLDOMDocumentType interface in our example application. First, add another command button to the frmDOMTest form with the name cmdDocumentType and the caption Document Type. Then add the following code to the click event of this button:

 Private Sub cmdDocumentType_Click() Dim objDocumentType As IXMLDOMDocumentType Dim objXMLDoc As DOMDocument Set objXMLDoc = New DOMDocument objXMLDoc.async = False objXMLDoc.Load ("c:\Books.xml") Set objDocumentType = objXMLDoc.doctype Debug.Print objDocumentType.Name Debug.Print objDocumentType.xml Debug.Print objDocumentType.entities.length Debug.Print objDocumentType.entities.Item(0).xml End Sub 

When you run this example and click the DocumentType button, you'll see the following output:

 northwind:BOOKS <!DOCTYPE northwind:BOOKS SYSTEM "c:\Books.dtd"> 1 <!ENTITY copyright "©"> 

Once again, you have created a reference to an IXMLDOMDocument interface. With this reference, you can use the doctype property to get a reference to an IXMLDOMDocumentType interface. Then you use the name and xml properties of the IXMLDOMDocumentType interface to get a node's name and its XML content. Notice that the parameter entity was not included in the entities collection.

XMLDOMDocumentFragment Object

The XMLDOMDocumentFragment object will be used to create fragments of documents that can be appended to another document. When the XMLDOMDocumentFragment object is inserted into a document object, the root node of the XMLDOMDocumentFragment is not inserted, only its children. Thus, XMLDOMDocumentFragment objects are useful for inserting child elements into a document.

The XMLDOMDocumentFragment object implements the IXMLDOMDocumentFragment interface. This interface inherits all the IXMLDOMNode interface's methods and properties, but it doesn't extend the interface, so this interface has no additional methods or properties of its own.

XMLDOMElement Object

The XMLDOMElement object contains the elements in the document and is the most common node. The text nodes belonging to an element object contain the content of the element. If there is no text content, the XMLDOMText object will be null. This object implements the IXMLDOMElement interface. When working with the IXMLDOMElement interface, you must know beforehand what the names of the elements and attributes are that you want to retrieve and place them in the code. This is because the IXMLDOMElement interface sets and retrieves attributes and elements by their names.

In addition to the methods and properties of the IXMLDOMNode interface, the IXMLDOMElement interface has the following extended property and methods:

Extended IXMLDOMElement Property

NameDescription
tagName Sets or returns the name of the element

Extended IXMLDOMElement Methods

NameDescription
getAttribute (attributeName) Returns the value of the attribute with the specified attributeName.
getAttributeNode (attributeName) Returns the attribute node object with the specified attributeName.
getElementsByTagName (elementName) Returns an XMLDOMNodeList object that contains all the descendant elements named elementName.
normalize() Combines the adjacent text nodes into one unified text node. Normalizes all descendant text nodes of the element.
removeAttribute (attributeName) Removes the value of the attribute named attributeName.
removeAttributeNode (attributeNode) Removes the attribute node named attributeNode and returns the node. If there is a default value in the schema or DTD, a new attribute node will be created with the default value.
setAttribute (attributeName, newValue) Sets the attribute node named attributeName to the value newValue.
setAttributeNode (attributeName) Adds a new attribute node to the element. An existing attribute node by the same name will be replaced.

You can get a reference to an IXMLDOMElement interface by using the selectNodes method and XSL. You will now create an example to select a single element node. To do so, follow these steps:

  1. Add another command button to the frmDOMTest form with the name cmdElement and the caption Element.
  2. Insert the following code into the click event handler of this button:
  3.  Private Sub cmdElement_Click() Dim objXMLDoc As DOMDocument Dim objElement As IXMLDOMElement Set objXMLDoc = New DOMDocument objXMLDoc.async = False objXMLDoc.Load ("c:\Books.xml") Set objElement = objXMLDoc.selectNodes("//item/*").Item(1) Debug.Print objElement.xml Set objElement = Nothing Set objXMLDoc = Nothing End Sub 

This example application selects the second child node of the item element. Then it retrieves the entire XML content of this node by using the xml property. When you run this example and click the Element button, the result is as follows:

 <author>Danzig</author> 

You can get a reference to the XMLDOMAttribute, XMLDOMEntity, XMLDOMEntityReference, XMLDOMNotation, XMLDOMCharacterData, XMLDOMText, XMLDOMCDATASection, XMLDOMComment, and XMLDOMProcessingInstruction by using XSL. You can get references to these node objects just as we used the XSL statement "//item/*" to get references to the node item in the previous application. (We will discuss the XSL syntax in detail in Chapter 12. ) So in the following sections, we'll examine these interfaces without demonstrating how to use them in the applications.

XMLDOMAttribute Object

The XMLDOMAttribute object represents an attribute node of the XMLDOMElement object. This object implements the IXMLDOMAttribute interface. In addition to the properties and methods it inherits from the IXMLDOMNode interface, the IXMLDOMAttribute interface has the following additional properties:

Extended IXMLDOMAttribute Properties

NameDescription
name Sets or returns the name of the attribute
value Sets or returns the value of the attribute

NOTE
The W3C specification lists this object as the attr object, instead of the XMLDOMAttribute object.

XMLDOMEntity Object

The XMLDOMEntity object represents a parsed or unparsed entity declared in a DTD. The XMLDOMEntity object is not the entity declaration. This object implements the IXMLDOMEntity interface. The properties of this interface are read-only. Like most of the other DOM interfaces, this interface inherits the IXMLDOMNode interface too. In addition to the IXMLDOMNode properties and methods, the IXMLDOMEntity object extends the IXMLDOMNNode object with the following properties:

Extended IXMLDOMEntity Properties

NameDescription
publicID Returns the value of the PUBLIC identifier for the entity node
systemID Returns the value of the SYSTEM identifier for the entity node
notationName Returns the notation name

XMLDOMEntityReference Object

The XMLDOMEntityReference object represents an entity reference node contained in the XML document. Remember that an XML processor doesn't expand the entities until they are needed. Thus, if the XML processor doesn't expand the entities, there will be no XMLDOMEntityReference objects. The replacement text will be located in the text property. The IXMLDOMEntityReference interface implemented by the XMLDOMEntityReference object inherits all the methods and properties of, but does not extend, the IXMLDOMNode interface.

XMLDOMNotation Object

The XMLDOMNotation object represents a notation declared in the DTD with the declaration <!NOTATION>. The XMLDOMNotation object implements the IXMLDOMNotation interface that inherits all the methods and properties of the IXMLDOMNode interface and extends the IXMLDOMNode interface with the following properties:

Additional IXMLDOMNotation Properties

NameDescription
publicID Returns the value of the PUBLIC identifier for the notation node
systemID Returns the value of the SYSTEM identifier for the notation node

XMLDOMCharacterData Object

The XMLDOMCharacterData object makes it easier to work with the text content in an XML document. The IXMLDOMCharacterData interface implemented by the XMLDOMCharacterData object also inherits the IXMLDOMNode interface, so it includes all the properties and methods of the IXMLDOMNode interface. Moreover, it extends the IXMLDOMNode interface with the following properties and methods:

Extended IXMLDOMCharacterData Properties

NameDescription
data Contains the node's data. The actual data will depend on the type of node.
length Returns the number of characters in the data string.

Extended IXMLDOMCharacterData Methods

NameDescription
appendData (text) Appends the text argument onto the existing data string
deleteData (charOffset, numChars) Deletes numChars characters off the data string starting at charOffset
insertData (charOffset, text) Inserts the supplied text into the data string at the charOffset
replaceData (charOffset, numChars, text) Replaces numChars characters with the supplied text starting at charOffset
substringData (charOffset, numChars) Returns the numChars characters as a string, starting at charOffset, in the data string

XMLDOMText Object

The XMLDOMText object represents the text node of an element or an attribute. You can use the XMLDOMText object to build text nodes and append them into an XML document. The IXMLDOMText interface implemented by the XMLDOMText object inherits the IXMLDOMCharacterData interface and extends it with the following method:

Extended IXMLDOMText Method

NameDescription
splitText (charOffset) Splits the node into two nodes at the specified character offset and then inserts the new node into the XML document immediately following the node

XMLDOMCDATASection Object

An XMLDOMCDATASection object is used for sections of text that are not to be interpreted by the processor as markup. The XMLDOMCDATASection object implements the IXMLDOMCDATASection interface. This interface inherits the IXMLDOMText interface and has the same methods and properties as the IXMLDOMText interface.

XMLDOMComment Object

The XMLDOMComment object contains comments that are in the XML document. The IXMLDOMComment interface implemented by this object inherits the IXMLDOMCharacterData interface and also possesses the same methods and properties as IXMLDOMCharacterData. The IXMLDOMComment interface does not extend the IXMLDOMCharacterData interface.

XMLDOMProcessingInstruction Object

The XMLDOMProcessingInstruction object contains the processing instructions in the document between the <? tag and the ?> tag. The content enclosed in these two tags is divided into the target and data content. The IXMLDOMProcessingInstruction interface implemented by the XMLDOMProcessingInstruction object inherits the IXMLDOMNode interface and has the same methods as the IXMLDOMNode interface. It extends the IXMLDOMNode interface with the following properties:

Extended IXMLDOMProcessingInstruction Properties

NameDescription
data Sets or returns the content of the processing instruction, which doesn't contain the target
target Sets or returns the target application to which the processing instruction is directed

XMLDOMImplementation Object

Because different applications that support XML can support different features of XML, the W3C included the XMLDOMImplementation object, which can be used to determine whether certain features are supported in a particular application. The XMLDOMImplementation object implements the IXMLDOMImplementation interface. This interface has one method called hasFeature that returns true if the specified feature is implemented by the specified version of the XML DOM implementation. To see how this object works, add another command button to the frmDOMTest form with the name cmdImplementation and the caption Implementation. Add the following code to the click event of this button:

 Private Sub cmdImplementation _Click() Dim objImplementation As IXMLDOMImplementation Dim objXMLDoc As DOMDocument Set objXMLDoc = New DOMDocument objXMLDoc.async = False objXMLDoc.Load ("c:\Books.xml") Set objImplementation = objXMLDoc.implementation 'Currently accepted values for feature: XML, DOM, and MS-DOM Debug.Print "MS-DOM: " & _ objImplementation.hasFeature("MS-DOM", "1.0") Debug.Print "XML: " & _ objImplementation.hasFeature("XML", "1.0") Debug.Print "DOM: " & _ objImplementation.hasFeature("DOM", "1.0") End Sub 

If you have Internet Explorer 5 installed on your computer, running this application and clicking the Implementation button will give you the following results:

 MS-DOM: True XML: True DOM: True 

HasFeature returning true shows that Internet Explorer 5 supports XML, DOM, and the MS-DOM.

XMLDOMParseError Object

The XMLDOMParseError object is an extension to the W3C specification. It can be used to get detailed information on the last error that occurred while either loading or parsing a document. The XMLDOMParseError object implements the IXMLDOMParseError interface that has the following properties:

IXMLDOMParseError Properties

NameDescription
errorCode Returns the error number or error code as a decimal integer.
filepos Returns the absolute character position in the document where the error occurred.
line Returns the number of the line where the error occurred.
linepos Returns the absolute character position in the line where the error occurred.
reason Returns a description of the source and reason for the error. If the error is in a schema or DTD, it can include the URL for the DTD or schema and the node in the schema or DTD where the error occurred.
srcText Returns the full text of the line that contains the error. If the error cannot be assigned to a specific line, an empty line is returned.
url Returns the URL for the most recent XML document that contained an error.

To see how the IXMLDOMParseError interface is used, we will make a change to the first line of code in the Books.dtd: <!ELEMENT northwind:BOOKS (item)> by removing the northwind: from the line, as shown here:

 <!ELEMENT BOOKS (item )> 

Add another command button to the frmDOCTest form with the name cmdParseError and the caption ParseError. In the click event handler of this button, place the following code:

 Private Sub cmdParseError _Click() Dim objXMLDoc As DOMDocument Dim objXMLParseError As IXMLDOMParseError On Error GoTo cmdParseErrorError Set objXMLDoc = New DOMDocument objXMLDoc.async = False objXMLDoc.Load ("c:\Books.xml") 'Check whether there was an error parsing the file using the 'parseError object. If objXMLDoc.parseError.errorCode <> 0 Then 'If there was an error, raise it to jump into error trap. Err.Raise objXMLDoc.parseError.errorCode End If Exit Sub 'Error Trap cmdParseErrorError: Set objXMLParseError = objXMLDoc.parseError With objXMLParseError 'Because of the With objXMLParseError, .errorCode is the 'same as objXMLParseError.errorCode. 'First check whether the error was caused by a parse error. If .errorCode <> 0 Then Debug.Print "The following error occurred:" & vbCrLf & _ "error code: " & .errorCode & vbCrLf & _ "error file position: " & .filepos & vbCrLf & _ "error line: " & .Line & vbCrLf & _ "error line position: " & .linepos & vbCrLf & _ "error reason: " & vbCrLf & .reason & vbCrLf & _ "error source text: " & vbCrLf & .srcText & _ " Test:cmdParseError" Else 'If the error was not caused by a parse error, use 'regular Visual Basic error object. MsgBox "The following error has occurred:" & vbCrLf & _ "Error Description: " & Err.Description & _ vbCrLf & _ "Error Source: " & vbCrLf & Err.Source & _ " Test:cmdParseError" & vbCrLf & _ "Error Number: " & Err.Number End If End With Set objXMLParseError = Nothing Set objXMLDoc = Nothing End Sub 

Before you actually run this code, take a look at it to see what an error handler in production code should look like. A parse error does not raise its error. After the parse error occurs, the Visual Basic error number (Err.Number) is still 0. Thus, you must use the ParseError object to check for an error after you load an XML document. If there is a parse error, you can raise an error, as was done above, to bring you into the error trap.

The error trap provides a message if the error occurred in parsing the file. If the error was caused for some other reason, the standard Visual Basic Err error object is used. Also notice that the name of the application and the method are included in the source, making it easier to find and fix bugs.

Now you can run the updated application and click the ParseError button. With the change in the DTD, you will receive the following message:

 The following error occurred: error code: -1072898035 error file position: 137 error line: 3 error line position: 64 error reason: The element 'northwind:BOOKS' is used but not declared in the DTD/Schema. error source text: <northwind:BOOKS xmlns:northwind="www.northwindtraders.com/PO"> Test:cmdParseError error source text: <northwind:BOOKS xmlns:northwind="www.northwindtraders.com/PO"> 

In this case, because the DTD has no awareness of namespaces, the namespace qualified northwind:BOOKS in the XML document no longer matches the DTD declaration.

To create a different error, change the DTD back to its original form by adding back the northwind:. Remove #FIXED "www. northwindtraders.com/PO" from the second line in the DTD, and the second line will look as follows:

 <!ATTLIST ":BOOKS xmlns: "CDATA> 

Now run the application and click the ParseError button; the error message will look as follows:

 The following error occurred: error code: -1072896766 error file position: 86 error line: 2 error line position: 51 error reason: A string literal was expected, but no opening quote character was found. error source text: <!ATTLIST northwind:BOOKS xmlns:northwind CDATA> Test:cmdParseError error source text: <!ATTLIST northwind:BOOKS xmlns:northwind CDATA> 

Notice that the error source text is now the information from the DTD. The reason might not be that obvious, but by looking at the error reason you will see that you need to include #REQUIRED, #FIXED, or #IMPLIED in the DTD. You must use #FIXED because this is a namespace attribute.

XTLRuntime Object

The XTLRuntime object works with XSL style sheets. It implements the IXTLRuntime interface that has nine methods: absoluteChildNumber, ancestorChildNumber, childNumber, depth, formatDate, formatIndex, formatNumber, formatTime, and uniqueID. We will cover XSL style sheets and these methods in Chapter 12.

XMLHTTPRequest Object

The XMLHTTPRequest object, which is an extension of the W3C specification, can be used to send and receive HTTP messages to and from a Web server. Once a message is received, it can be parsed by XML DOM objects. You could use the XMLHTTPRequest object to create applications that build and send SOAP messages to the server. This object implements the IXMLHTTPRequest interface, which has the following properties and methods:

IXMLHTTPRequest Properties

NameDescription
readyState Indicates the current state of the document being loaded. The value changes as the XML document loads.
responseBody Returns the response as an array of unsigned bytes.
responseStream Returns the response object as an IStream object.
responseText Returns the response object as a text string.
responseXML Returns the response as an XML document. When this property is used, validation is turned off to prevent the parser from attempting to download a linked DTD or schema.
status Returns a status code as a long integer.
statusText Returns the status as a string.

IXMLHTTPRequest Methods

NameDescription
abort()* Cancels the current HTTP request
getAllResponseHeaders()* Returns all the HTTP headers as name value pairs separated by carriage return-linefeeds
getResponseHeader (headerName)* Gets the response header with the name headerName
open (method, url, async, userID, password)* Initializes a request and specifies the HTTP method, the URL, and if the response is asynchronous, the user information
send()* Sends an HTTP request to the server and waits to receive a response
setRequestHeader (headerName, value) Sets HTTP headers that are sent to the server

This chapter has described a complete set of objects that can allow you to manipulate XML information and send HTTP streams to and from a Web server. It's time we look at a more complete example of using some of these objects, including the XMLHTTPRequest object. To do this, we will write the code to create a SOAP client and server application.



Developing XML Solutions
Developing XML Solutions (DV-MPS General)
ISBN: 0735607966
EAN: 2147483647
Year: 2000
Pages: 115
Authors: Jake Sturm

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net