
/** 
 * ReadXML.java
 * 
 * Based on the Apache's Xerces sample "DOMCount.java" and IBM's domOne.java (www.ibm.com/developerWorks).
 * You can download the Xerces XML parser at 
 * http://xml.apache.org/dist/xerces-j/.
 *
 * In order to compile this sample, xerces.jar must be in your CLASSPATH.
 *
 * JPM, December 2000
**/

import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import org.apache.xerces.dom.TextImpl;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *  class ReadXML
 *
 *  Illustrates how to go through a DOM tree.
 *
 * @author     Jean-Philippe Martin 
 * @created    December 2000 
 */
public class ReadXML {
    private static boolean setValidation    = false; //defaults
    private static boolean setNameSpaces    = true;
    private static boolean setDeferredDOM   = true;

  /**
   *  Main entry point 
   *
   * @param  uri  file (or URL) to be parsed 
   */
  public static void parseAndPrint(String uri) {

        try {
            org.apache.xerces.parsers.DOMParser parser = new org.apache.xerces.parsers.DOMParser();
            ReadXML reader = new ReadXML();
            long before = System.currentTimeMillis();
            parser.setFeature( "http://apache.org/xml/features/dom/defer-node-expansion",

                               setDeferredDOM );
            parser.setFeature( "http://xml.org/sax/features/validation", 
                               setValidation );
            parser.setFeature( "http://xml.org/sax/features/namespaces",
                               setNameSpaces );

            parser.parse(uri);
            reader.printDOMTree(parser.getDocument());
            long after = System.currentTimeMillis();
            System.out.println("\n\nDone. Processing took "+(after - before)+"ms.");
        } catch (Exception e) {
            e.printStackTrace(System.err);
        }
  
  }


  /**
   *  Prints the specified node, then prints all of its children. 
   *
   * @param  node  the Node to print 
   */
  public void printDOMTree(Node node) {
    int type = node.getNodeType();
    switch (type) {
// print the document element
      case Node.DOCUMENT_NODE:
      {
        System.out.println("<?xml version=\"1.0\" ?>");
        printDOMTree(((Document) node).getDocumentElement());
        break;
      }
// print element with attributes
      case Node.ELEMENT_NODE:
      {
        System.out.print("<");
        System.out.print(node.getNodeName());
        NamedNodeMap attrs = node.getAttributes();
        for (int i = 0; i < attrs.getLength(); i++) {
          Node attr = attrs.item(i);
          System.out.print("" + attr.getNodeName() + 
              "=\"" + attr.getNodeValue() + 
              "\"");
        }
        System.out.println(">");
        NodeList children = node.getChildNodes();
        if (children != null) {
          int len = children.getLength();
          for (int i = 0; i < len; i++) {
            printDOMTree(children.item(i));
          }
        }
        break;
      }
// handle entity reference nodes
      case Node.ENTITY_REFERENCE_NODE:
      {
        System.out.print("&");
        System.out.print(node.getNodeName());
        System.out.print(";");
        break;
      }
// print cdata sections
      case Node.CDATA_SECTION_NODE:
      {
        System.out.print("<![CDATA[");
        System.out.print(node.getNodeValue());
        System.out.print("]]>");
        break;
      }
// print text.
      case Node.TEXT_NODE:
      {
        System.out.print(node.getNodeValue());
        break;
      }
// print processing instruction
      case Node.PROCESSING_INSTRUCTION_NODE:
      {
        System.out.print("<?");
        System.out.print(node.getNodeName());
        String data = node.getNodeValue();
         {
          System.out.print("");
          System.out.print(data);
        }
        System.out.print("?>");
        break;
      }
    }
    if (type == Node.ELEMENT_NODE) {
      System.out.println();
      System.out.print("</");
      System.out.print(node.getNodeName());
      System.out.print('>');
    }
  }

  /**
   *  Main program entry point. 
   *
   * @param  argv  URI of the XML file (or URL) to be parsed 
   */
  public static void main(String argv[]) {
    if (argv.length == 0) {
      System.out.println("Usage: java ReadXML uri");
      System.out.println(" where uri is the URI of the XML document you want to print.");
      System.out.println(" Sample: java ReadXML CDAlbum.xml");
      System.exit(1);
    }
    ReadXML.parseAndPrint(argv[0]);
  }
}

