Jim,
The api written here is Java's JAXP stuff. Following is the java code order.java -
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import java.io.File;
import org.w3c.dom.*;
public class order{
public static int depth;
public static void showAttributes(Node element)
{
NamedNodeMap nnMap = element.getAttributes();
Node indexedNode;
for(int i=0; i<nnMap.getLength(); i++)
{
for(int j=0; j<depth; j++) System.out.print(" ");
indexedNode = nnMap.item(i);
System.out.println("ATTR::"+indexedNode.getNodeName()+"="+
indexedNode.getNodeValue()+"("+getNodeType(indexedNode)+")");
}
}
public static
String getNodeType(Node node)
{
short type;
type = node.getNodeType();
String retNode = "UNKNOWN";
if(type == node.ELEMENT_NODE) retNode="ELEMENT_NODE";
if(type == node.ATTRIBUTE_NODE) retNode="ATTRIBUTE_NODE";
if(type == node.COMMENT_NODE) retNode="COMMENT_NODE";
if(type == node.PROCESSING_INSTRUCTION_NODE) retNode="PROCESSING_INSTRUCTION_NODE";
if(type == node.ENTITY_REFERENCE_NODE) retNode="ENTITY_REFERENCE_NODE";
if(type == node.ENTITY_NODE) retNode="ENTITY_NODE";
if(type == node.NOTATION_NODE) retNode="NOTATION_NODE";
if(type == node.TEXT_NODE) retNode="TEXT_NODE";
if(type == node.DOCUMENT_NODE) retNode="DOCUMENT_NODE";
if(type == node.DOCUMENT_TYPE_NODE) retNode="DOCUMENT_TYPE_NODE";
if(type == node.CDATA_SECTION_NODE) retNode="CDATA_SECTION_NODE";
if(type == node.DOCUMENT_FRAGMENT_NODE) retNode="DOCUMENT_FRAGMENT_NODE";
return retNode;
}
public static void recurseNodes(Node node)
{
for(int i=0;i<depth; i++) System.out.print(" ");
// print the node information
if(node.getNodeType() == node.TEXT_NODE)
{
if(node.getNodeValue().trim().length() > 0){
System.out.println(node.getNodeName()+"="+
node.getNodeValue()+"("+getNodeType(node)+")");
}
else
{
System.out.println(node.getNodeName()+"="+"("+getNodeType(node)+")");
}
}
else
{
System.out.println(node.getNodeName()+"="+
node.getNodeValue()+"("+getNodeType(node)+")");
}
// print the node attributes
if(node.getNodeType() == node.ELEMENT_NODE)
showAttributes(node);
// recurse thru the children
Node firstChild = node.getFirstChild();
while(firstChild!=null)
{
depth ++;
recurseNodes(firstChild);
firstChild = firstChild.getNextSibling();
}
depth--;
}
public static void main (String args[]) {
File docFile = new File("aa.xml");
Document doc = null;
NamedNodeMap nnMap = null;
int i;
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(true);
dbf.setExpandEntityReferences(false);
DocumentBuilder docb = dbf.newDocumentBuilder();
doc = docb.parse(docFile);
Element root = doc.getDocumentElement();
System.out.println("RootElement::"+root.getNodeName());
NodeList nList = root.getChildNodes();
System.out.println("No. of children for root node "+
nList.getLength());
depth=0;
recurseNodes(root);
// Details of the DTD
System.out.println("-------------DTD DETAILS----------");
DocumentType docType = doc.getDoctype();
System.out.println("DTD Name ::"+docType.getName());
nnMap = docType.getEntities();
System.out.println("No. of general Entities ::"+nnMap.getLength());
// Entity information
for(i=0;i<nnMap.getLength();i++)
{
System.out.println("Index ::"+i+""+nnMap.item(i).getNodeName()+"="+
nnMap.item(i).getNodeValue());
}
nnMap = docType.getNotations();
System.out.println("No. of Notations ::"+nnMap.getLength());
// Entity information
for(i=0;i<nnMap.getLength();i++)
{
System.out.println("Index ::"+i+""+nnMap.item(i).getNodeName()+"="+
nnMap.item(i).getNodeValue());
System.out.println("Notation SYSTEM ::"+((Notation)nnMap.item(i)).getSystemId());
}
} catch (Exception e) { System.out.println("EXCEPTION");}
}
}
============================================
Below is the xml file to parse -
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE orders [
<!ELEMENT orders (order*)>
<!ELEMENT order (customerid, status, item*)>
<!ELEMENT item ANY>
<!ELEMENT status (#PCDATA)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ELEMENT qty (#PCDATA)>
<!ATTLIST customerid limit CDATA #REQUIRED>
<!ATTLIST orders Notation ENTITY #IMPLIED>
<!ATTLIST item instock CDATA #REQUIRED
itemid CDATA #REQUIRED>
<!ENTITY jaya "WB78">
<!ENTITY jayaTwo "&elementEntity;">
<!ELEMENT jaya (#PCDATA)>
<!ENTITY elementEntity "<jaya>jayadev</jaya>">
<!NOTATION jaya SYSTEM "jaya.exe">
<!ENTITY giffile SYSTEM "demo.gif" NDATA jaya>
]>
<?PI-1 this is first processing instruction?>
<orders Notation="giffile">
<order>
<?PI-2 this is second processing instruction?>
<customerid limit="1000">12341</customerid>
<status>pending</status>
<item instock="Y" itemid="SA15">
<![CDATA[hi there]]>
<name>Silver Show Saddle, 16 inch</name>
<price>825.00</price>
<qty>1</qty>
</item>
<item instock="N" itemid="C49">
<![CDATA[hi there]]>
<name>Premium Cinch</name>
<price>49.00</price>
<qty>1</qty>
</item>
</order>
<order>
<?PI-3 this is third processing instruction?>
<customerid limit="150">251222</customerid>
<status>pending</status>
<item instock="Y" itemid="&jaya;">
&jayaTwo;
<!-- &giffile; -->
<![CDATA[hi there]]>
<name>Winter Blanket (78 inch) &jaya;</name>
<price>20</price>
<qty>10</qty>
</item>
</order>
</orders>
================================================
Things missing from the above exercise -
1) Exception handling not elaborate; simply using more generic Exception class
2) Insertion, deletion and creation of new elements, attributes, etc i.e., modification of an existing DOM tree.
If you run the above example in Java, you can see the tree-like structure (nodes indented) along with the node type printed besides each node. You can easily extend on this stuff to
test other features of the DOM API