- Defining the Document Object Model
- DOM Core Level I
- Creating Document Objects
- Node Interface
- NodeList and NamedNodeMap
- Document Interface
- Element Interface
- Attr Interface
- Additional Interfaces
- Creating DOM Elements
- DOM Level II
- The DOM Core Defined
- Implementation Anomalies
- Summary
- Suggested for Further Study
- Further Reading
Document Interface
The Document interface is the topmost interface in the XML document tree. It contains nine defined methods, five additional methods derived from the various document attributes, and those methods and variables inherited from the Node interface. The Document interface performs four major functions, allowing developers to do the following:
Query for information about the document, such as its name, entities, and notations.
Query for information about the implementation, such as what version of the DOM core is supported.
Create documents, DocumentFragments, Elements, Nodes, Attributes, Comments, and so on.
Traverse the document tree.
The Document object always has Node type DOCUMENT_NODE. The following sections describe the methods on the Document object.
Methods that Return Information About the Document or Implementation
There are a number of methods for returning information about the DTD associated with a document. The most common methods are listed below.
DocumentType getDocType() Returns a DocumentType object that has three methods. NamedNodeMap getEntities() returns all the defined entities within the document. NamedNodeMap getNotations() returns all the notations, and String getName() returns the name immediately following the DOCTYPE keyword within the DTD.
DOMImplementation getImplementation() Returns a DOMImplementation object that has a single method boolean hasFeature();. A typical use might be getImplementation.hasFeature("XML,"1.0");.
Methods that Return Information About Descendant Nodes
In addition to those inherited from the node interface, two methods exist for accessing the children of a Node.
Element getDocumentElement(...) Returns the root Element of the Document. In the case of HTML it is the element containing the <html> tag. In XML, this method returns the Element representing the root of the XML tree.
NodeList getElementsByTagName(String tag) Returns a NodeList of all the nodes that match the given tag. This method is interesting in that it returns all the nodes represented by the tag regardless of their level within the XML tree.
Methods that Create Descendant Nodes
There are a number of methods that can be used to create child nodes, which can then be inserted into an XML document. The various Create methods can be used to create empty elements that can then be inserted into a DOM tree.
Attr createAttribute(String name) Creates an attribute of the given name.
CDATASection createCDATASection(String name) Creates a CDATA node.
Comment createComment(String comment) Create a comment.
DocumentFragment createDocumentFragment() Creates an empty document that can then be used to add additional elements.
Element createElement(String tag) Creates an empty element of name tag. This element may later have child nodes added to it.
EntityReference createEntityReference(String name) Creates an EntityReference of the given name.
ProcessingInstruction createProcessingInstruction(String target, String data) Creates a ProcessingInstruction node.
TextNode createTextNode(String data) Creates a TextNode with the given data as its value.
Before we move on and examine the Element interface, a short example of the use of getElementsByTag(...) would be beneficial (see Listing 3.5).
Listing 3.5 ElementsByTag.javaUsing getElementsByTag
1: /* 2: * @(#)ElementsByTag.java 1.0 99/05/28 3: * 4: * Copyright (c) 1999 Sams Publishing. All Rights Reserved. 5: * 6: */ 7: 8: import java.io.*; 9: import com.sun.xml.tree.*; 10: import org.w3c.dom.*; 11: 12: public class ElementsByTag 13: { 14: public static void main (String argv []) 15: { 16: FileInputStream inStream; 17: Document document; 18: String xmlDocumentPath = "catalog.xml"; 19: try 20: { 21: inStream = new FileInputStream(xmlDocumentPath); 22: document = XmlDocument.createXmlDocument(inStream,true); 23: 24: NodeList entries = document.getElementsByTagName( "entry" ); 25: if ( entries.getLength()== 0) 26: { 27: System.out.println("No entries in this catalog, exiting"); 28: System.exit(0); 29: } 30: 31: for (int i = 0; i < entries.getLength(); i++) 32: { 33: System.out.print(i + " "); 34: Element entryNode = (Element) entries.item(i); 35: NodeList titles = entryNode.getElementsByTagName ("title"); 36: if ( titles.getLength() == 0) 37: System.out.println("Unknown"); 38: else 39: { 40: Node titleElement = titles.item(0); 41: NodeList titleValues = titleElement.getChildNodes(); 42: Node titleValue = titleValues.item(0); 43: System.out.print (" "+titleValue.getNodeValue()); 44: } 45: 46: // 47: // Now show author entries 48: // 49: NodeList authors = entryNode. getElementsByTagName ("author"); 50: if ( authors.getLength() == 0) 51: System.out.println("Unknown"); 52: else 53: { 54: . . . 55: } 56: // 57: // Now show prices 58: // 59: NodeList prices = entryNode.getElementsByTagName ("price"); 60: if ( prices.getLength() == 0) 61: System.out.println("Unknown"); 62: else 63: { 64: . . . 65: System.out.println(""); 66: } 67: } 68: catch (Exception e) 69: { 70: System.out.println( "Unexpected exception reading document!" +e); 71: System.exit (0); 72: } 73: 74: 75: } 76: }
Listing 3.5 produces output similar to Listing 3.6.
Listing 3.6 Output of GetElementsByTag.java
1: C:\java sams.chp3.GetElementsByTab 2: 0 Better Living Thru Chemistry I. W. Books 9.95 discount:retail cur:us 7.95 discount: wholesale cur:us 3: 1 Special Edition:Using XML and Java 2.0 Al Saganich Mike Daconta 9.95 discount: retail cur:us 7.95 discount:wholesale cur:us 4: 2 Java 2.0 and JavaScript for C/C++ Programmers Al Saganich Mike Daconta 59.95 discount:retail cur:us 74.95 discount:wholesale cur:us 5: 3 Converational French R. Weiman 7.00 discount:retail cur:can 4.25 discount: wholesale cur:us
In GetElementsByTag.java, we use the getElementsByTag method multiple times on both the Document object and its underlying Element object. As we'll see in the next section, the Element interface has an identical method to the Document.getElementsByTag() method.
Again we use the method several times, once to return a list of the entry elements and within entries to directly get entry information such as title, author, and price. Both are simple enough, but what is important to understand is that we could have completely ignored the fact that titles exist within entries. If we remember that our catalog contains entries and entry titles, we could have just as easily listed all the titles with the catalog directly with the following code snippet:
NodeList document = entryNode.getElementsByTagName ("title");
This command takes the parent Document object, rather then acting on a child node somewhere down the DOM document. The code snippet also returns all title objects. For example, if we are only interested in collecting all the currencies associated with a catalog, we could write the following:
NodeList document = entryNode.getElementsByTagName ("price");
which, again, takes the parent Document object and returns all the child price Elements, regardless of where they fall in the DOM tree. getElementsByTagName is certainly one of the more powerful methods in the entire DOM API.