19.8 A Simple DOM Application

     

Example 19-1 illustrates how you might use the interfaces discussed in this chapter in a typical programming situation. This application takes a document that uses the furniture.dtd sample DTD from Chapter 21 and validates that the parts list included in the document matches the actual parts used within the document.

Example 19-1. Parts checker application
 /**  * PartsCheck.java  *  * DOM Usage example from the O'Reilly _XML in a Nutshell_ book.  *  */    // we'll use the Apache Software Foundation's Xerces parser. import org.apache.xerces.parsers.*; import org.apache.xerces.framework.*;    // import the DOM and SAX interfaces import org.w3c.dom.*; import org.xml.sax.*;    // get the necessary Java support classes import java.io.*; import java.util.*;    /**  * This class is designed to check the parts list of an XML document that  * represents a piece of furniture for validity.  It uses the DOM to  * analyze the actual furniture description and then check it against the  * parts list that is embedded in the document.  */ public class PartsCheck {   // static constants   public static final String FURNITURE_NS =       "http://namespaces.oreilly.com/furniture/";   // contains the true part count, keyed by part number   HashMap m_hmTruePartsList = new HashMap( );      /**    * The main function that allows this class to be invoked from the command    * line.  Check each document provided on the command line for validity.    */   public static void main(String[  ] args) {     PartsCheck pc = new PartsCheck( );        try {       for (int i = 0; i < args.length; i++) {         pc.validatePartsList(args[i]);       }     } catch (Exception e) {       System.err.println(e);     }   }      /**    * Given a system identifier for an XML document, this function compares    * the actual parts used to the declared parts list within the document.  It    * prints warnings to standard error if the lists don't agree.    */   public void validatePartsList(String strXMLSysID) throws IOException,       SAXException   {     // create a new parser     DOMParser dp = new DOMParser( );        // parse the document and get the DOM Document interface     dp.parse(strXMLSysID);     Document doc = dp.getDocument( );        // get an accurate parts list count     countParts(doc.getDocumentElement( ), 1);        // compare it to the parts list in the document     reconcilePartsList(doc);   }      /**    * Updates the true parts list by adding the count to the current count    * for the part number given.    */   private void recordPart(String strPartNum, int cCount)   {     if (!m_hmTruePartsList.containsKey(strPartNum)) {       // this part isn't listed yet       m_hmTruePartsList.put(strPartNum, new Integer(cCount));     } else {       // update the count       Integer cUpdate = (Integer)m_hmTruePartsList.get(strPartNum);       m_hmTruePartsList.put(strPartNum, new Integer(cUpdate.intValue( ) + cCount));     }   }      /**    * Counts the parts referenced by and below the given node.    */   private void countParts(Node nd, int cRepeat)   {     // start the local repeat count at 1     int cLocalRepeat = 1;        // make sure we should process this element     if (FURNITURE_NS.equals(nd.getNamespaceURI( ))) {       Node ndTemp;          if ((ndTemp = nd.getAttributes( ).getNamedItem("repeat")) != null) {         // this node specifies a repeat count for its children         cLocalRepeat = Integer.parseInt(ndTemp.getNodeValue( ));       }          if ((ndTemp = nd.getAttributes( ).getNamedItem("part_num")) != null) {         // start the count at 1         int cCount = 1;         String strPartNum = ndTemp.getNodeValue( );            if ((ndTemp = nd.getAttributes( ).getNamedItem("count")) != null) {           // more than one part needed by this node           cCount = Integer.parseInt(ndTemp.getNodeValue( ));         }            // multiply the local count by the repeat passed in from the parent         cCount *= cRepeat;            // add the new parts count to the total         recordPart(strPartNum, cCount);       }     }        // now process the children     NodeList nl = nd.getChildNodes( );     Node ndCur;        for (int i = 0; i < nl.getLength( ); i++) {       ndCur = nl.item(i);          if (ndCur.getNodeType( ) =  = Node.ELEMENT_NODE) {         // recursively count the parts for the child, using the local repeat         countParts(ndCur, cLocalRepeat);       }     }   }      /**    * This method reconciles the true parts list against the list in the document.    */   private void reconcilePartsList(Document doc)   {     Iterator iReal = m_hmTruePartsList.keySet( ).iterator( );        String strPartNum;     int cReal;     Node ndCheck;        // loop through all of the parts in the true parts list     while (iReal.hasNext( )) {       strPartNum = (String)iReal.next( );       cReal = ((Integer)m_hmTruePartsList.get(strPartNum)).intValue( );          // find the part list element in the document       ndCheck = doc.getElementById(strPartNum);          if (ndCheck =  = null) {         // this part isn't even listed!         System.err.println("missing <part_name> element for part #" +             strPartNum + " (count " + cReal + ")");       } else {         Node ndTemp;            if ((ndTemp = ndCheck.getAttributes( ).getNamedItem("count")) != null) {           int cCheck = Integer.parseInt(ndTemp.getNodeValue( ));              if (cCheck != cReal) {             // counts don't agree             System.err.println("<part_name> element for part #" +                 strPartNum + " is incorrect:  true part count = " + cReal +                 " (count in document is " + cCheck + ")");           }         } else {           // they didn't provide a count for this part!           System.err.println("missing count attribute for part #" +               strPartNum + " (count " + cReal + ")");         }       }     }   } } 

When this application is run over the bookcase .xml sample document from Chapter 21, it generates the following output:

 missing count attribute for part #HC (count 8)    <part_name> element for part #A is incorrect:  true part count = 2 (count in document is 1) 

To compile and use this sample application, download and install the Xerces Java Parser from the Apache-XML project (http://xml.apache.org/ xerces-j ). The code was originally compiled and tested with Sun's JDK Version 1.3.1.



XML in a Nutshell
XML in a Nutshell, Third Edition
ISBN: 0596007647
EAN: 2147483647
Year: 2003
Pages: 232

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