Java/XML/DOM Tree

Материал из Java эксперт
Перейти к: навигация, поиск

Accessing different types of DOM tree nodes

   <source lang="java">
    

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Attr; import org.w3c.dom.CharacterData; import org.w3c.dom.rument; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; public class Main {

 public static void main(String[] argv) throws Exception {
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   DocumentBuilder loader = factory.newDocumentBuilder();
   Document document = loader.parse("sample.xml");
   Element purchaseOrder = document.getDocumentElement();
   printElement(purchaseOrder, "");
 }
 static void printElement(Element element, String indent) {
   System.out.println("Element "" + element.getNodeName() + """);
   NodeList children = element.getChildNodes();
   for (int i = 0; i < children.getLength(); i++) {
     Node child = children.item(i);
     switch (child.getNodeType()) {
     case Node.ELEMENT_NODE:
       printElement((Element) child, indent + "\t");
       break;
     case Node.ATTRIBUTE_NODE:
       Attr attr = (Attr) child;
       System.out.println("\tAttribute: "" + attr.getName() + "" = "" + attr.getValue() + """);
       break;
     case Node.ruMENT_NODE:
       Comment comment = (Comment) child;
       System.out.println("\tComment: "" + comment.getData() + """);
       break;
     case Node.CDATA_SECTION_NODE:
       CharacterData cdata = (CharacterData) child;
       System.out.println("\tCDatat: "" + cdata.getData() + """);
       break;
     case Node.TEXT_NODE:
       Text text = (Text) child;
       System.out.println("\tText: "" + text.getData() + """);
       break;
     default:
       System.out.println("\tUnknown node type: "" + child.getNodeType() + """);
       break;
     }
   }
 }

}



 </source>
   
  
 
  



Copying a Subtree of Nodes from One DOM Document to Another

   <source lang="java">
    

import java.io.File; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class Main {

 public static void main(String[] argv) throws Exception {
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   factory.setValidating(true);
   factory.setExpandEntityReferences(false);
   Document doc1 = factory.newDocumentBuilder().parse(new File("filename"));
   NodeList list = doc1.getElementsByTagName("entry");
   Element element = (Element) list.item(0);
   Document doc2 = factory.newDocumentBuilder().parse(new File("infilename2.xml"));
   Node dup = doc2.importNode(element, true);
   doc2.getDocumentElement().appendChild(dup);
 }

}



 </source>
   
  
 
  



Copying a Subtree of Nodes in a DOM Document

   <source lang="java">
    

import java.io.File; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; public class Main {

 public static void main(String[] argv) throws Exception {
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   factory.setValidating(true);
   factory.setExpandEntityReferences(false);
   Document doc = factory.newDocumentBuilder().parse(new File("filename"));
   NodeList list = doc.getElementsByTagName("entry");
   Element element = (Element) list.item(0);
   Element dup = (Element) element.cloneNode(true);
   element.getParentNode().insertBefore(dup, element.getNextSibling());
 }

}



 </source>
   
  
 
  



Create new DOM tree with fully qualified element names

   <source lang="java">
    

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; public class Main {

 public static void main(String[] argv) throws Exception {
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   factory.setNamespaceAware(true);
   DocumentBuilder loader = factory.newDocumentBuilder();
   Document document = loader.newDocument();
   String docNS = "http://www.my-company.ru";
   Element order = document.createElementNS(docNS, "order");
   document.appendChild(order);
   order.setAttribute("xmlns", docNS);
 }

}



 </source>
   
  
 
  



Creating a new DOM tree

   <source lang="java">
    

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; public class Main {

 public static void main(String[] argv) throws Exception {
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   DocumentBuilder loader = factory.newDocumentBuilder();
   Document document = loader.newDocument();
   Element root = document.createElement("order");
   document.appendChild(root);
 }

}



 </source>
   
  
 
  



DOM Util: get Child Text

   <source lang="java">
 

import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class Main {

 public static String getChildText(Element parent, String childName) {
   NodeList list = parent.getElementsByTagName(childName);
   if (list.getLength() > 1) {
     throw new IllegalStateException("Multiple child elements with name " + childName);
   } else if (list.getLength() == 0) {
     return null;
   }
   Element child = (Element) list.item(0);
   return getText(child);
 }
 public static String getText(Element element) {
   StringBuffer buf = new StringBuffer();
   NodeList list = element.getChildNodes();
   boolean found = false;
   for (int i = 0; i < list.getLength(); i++) {
     Node node = list.item(i);
     if (node.getNodeType() == Node.TEXT_NODE) {
       buf.append(node.getNodeValue());
       found = true;
     }
   }
   return found ? buf.toString() : null;
 }

}


 </source>
   
  
 
  



Get Child Content

   <source lang="java">
 

import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class Main {

 public static String getChildContent(Element parent, String name, String missing, String empty) {
   Element child = getChild(parent, name);
   if (child == null) {
     return missing;
   } else {
     String content = (String) getContent(child);
     return (content != null) ? content : empty;
   }
 }
 public static Object getContent(Element element) {
   NodeList nl = element.getChildNodes();
   StringBuffer content = new StringBuffer();
   for (int i = 0; i < nl.getLength(); i++) {
     Node node = nl.item(i);
     switch (node.getNodeType()) {
     case Node.ELEMENT_NODE:
       return node;
     case Node.CDATA_SECTION_NODE:
     case Node.TEXT_NODE:
       content.append(node.getNodeValue());
       break;
     }
   }
   return content.toString().trim();
 }
 public static Element getChild(Element parent, String name) {
   for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
     if (child instanceof Element && name.equals(child.getNodeName())) {
       return (Element) child;
     }
   }
   return null;
 }

}


 </source>
   
  
 
  



Gets the child of the specified element having the specified name. If the child with this name doesn"t exist then null is returned instead.

   <source lang="java">
  

import java.util.ArrayList; import java.util.Iterator; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /**

* A utility class to cover up the rough bits of xml parsing
* 
* @author 
* @version $Revision: 2787 $
*/

@SuppressWarnings("unchecked") public class XmlHelper {

 /**
  * Returns an iterator over the children of the given element with the given
  * tag name.
  * 
  * @param element
  *          The parent element
  * @param tagName
  *          The name of the desired child
  * @return An interator of children or null if element is null.
  */
 public static Iterator getChildrenByTagName(Element element, String tagName) {
   if (element == null)
     return null;
   // getElementsByTagName gives the corresponding elements in the whole
   // descendance. We want only children
   NodeList children = element.getChildNodes();
   ArrayList goodChildren = new ArrayList();
   for (int i = 0; i < children.getLength(); i++) {
     Node currentChild = children.item(i);
     if (currentChild.getNodeType() == Node.ELEMENT_NODE
         && ((Element) currentChild).getTagName().equals(tagName)) {
       goodChildren.add(currentChild);
     }
   }
   return goodChildren.iterator();
 }
 /**
  * Gets the child of the specified element having the specified unique name.
  * If there are more than one children elements with the same name and
  * exception is thrown.
  * 
  * @param element
  *          The parent element
  * @param tagName
  *          The name of the desired child
  * @return The named child.
  * 
  * @throws Exception
  *           Child was not found or was not unique.
  */
 public static Element getUniqueChild(Element element, String tagName) throws Exception {
   Iterator goodChildren = getChildrenByTagName(element, tagName);
   if (goodChildren != null && goodChildren.hasNext()) {
     Element child = (Element) goodChildren.next();
     if (goodChildren.hasNext()) {
       throw new Exception("expected only one " + tagName + " tag");
     }
     return child;
   } else {
     throw new Exception("expected one " + tagName + " tag");
   }
 }
 /**
  * Gets the child of the specified element having the specified name. If the
  * child with this name doesn"t exist then null is returned instead.
  * 
  * @param element
  *          the parent element
  * @param tagName
  *          the name of the desired child
  * @return either the named child or null
  * @throws Exception
  */
 public static Element getOptionalChild(Element element, String tagName) throws Exception {
   return getOptionalChild(element, tagName, null);
 }
 /**
  * Gets the child of the specified element having the specified name. If the
  * child with this name doesn"t exist then the supplied default element is
  * returned instead.
  * 
  * @param element
  *          the parent element
  * @param tagName
  *          the name of the desired child
  * @param defaultElement
  *          the element to return if the child doesn"t exist
  * @return either the named child or the supplied default
  * @throws Exception
  */
 public static Element getOptionalChild(Element element, String tagName, Element defaultElement)
     throws Exception {
   Iterator goodChildren = getChildrenByTagName(element, tagName);
   if (goodChildren != null && goodChildren.hasNext()) {
     Element child = (Element) goodChildren.next();
     if (goodChildren.hasNext()) {
       throw new Exception("expected only one " + tagName + " tag");
     }
     return child;
   } else {
     return defaultElement;
   }
 }
 /**
  * Get the content of the given element.
  * 
  * @param element
  *          The element to get the content for.
  * @return The content of the element or null.
  * @throws Exception
  */
 public static String getElementContent(final Element element) throws Exception {
   return getElementContent(element, null);
 }
 /**
  * Get the content of the given element.
  * 
  * @param element
  *          The element to get the content for.
  * @param defaultStr
  *          The default to return when there is no content.
  * @return The content of the element or the default.
  * @throws Exception
  */
 public static String getElementContent(Element element, String defaultStr) throws Exception {
   if (element == null)
     return defaultStr;
   NodeList children = element.getChildNodes();
   String result = "";
   for (int i = 0; i < children.getLength(); i++) {
     if (children.item(i).getNodeType() == Node.TEXT_NODE
         || children.item(i).getNodeType() == Node.CDATA_SECTION_NODE) {
       result += children.item(i).getNodeValue();
     } else if (children.item(i).getNodeType() == Node.ruMENT_NODE) {
       // Ignore comment nodes
     }
   }
   return result.trim();
 }
 /**
  * Macro to get the content of a unique child element.
  * 
  * @param element
  *          The parent element.
  * @param tagName
  *          The name of the desired child.
  * @return The element content or null.
  * @throws Exception
  */
 public static String getUniqueChildContent(Element element, String tagName) throws Exception {
   return getElementContent(getUniqueChild(element, tagName));
 }
 /**
  * Macro to get the content of an optional child element.
  * 
  * @param element
  *          The parent element.
  * @param tagName
  *          The name of the desired child.
  * @return The element content or null.
  * @throws Exception
  */
 public static String getOptionalChildContent(Element element, String tagName) throws Exception {
   return getElementContent(getOptionalChild(element, tagName));
 }
 public static boolean getOptionalChildBooleanContent(Element element, String name)
     throws Exception {
   Element child = getOptionalChild(element, name);
   if (child != null) {
     String value = getElementContent(child).toLowerCase();
     return value.equals("true") || value.equals("yes");
   }
   return false;
 }

}


 </source>
   
  
 
  



Gets the child of the specified element having the specified unique name

   <source lang="java">
  

import java.util.ArrayList; import java.util.Iterator; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /**

* A utility class to cover up the rough bits of xml parsing
* 
* @author 
* @version $Revision: 2787 $
*/

@SuppressWarnings("unchecked") public class XmlHelper {

 /**
  * Returns an iterator over the children of the given element with the given
  * tag name.
  * 
  * @param element
  *          The parent element
  * @param tagName
  *          The name of the desired child
  * @return An interator of children or null if element is null.
  */
 public static Iterator getChildrenByTagName(Element element, String tagName) {
   if (element == null)
     return null;
   // getElementsByTagName gives the corresponding elements in the whole
   // descendance. We want only children
   NodeList children = element.getChildNodes();
   ArrayList goodChildren = new ArrayList();
   for (int i = 0; i < children.getLength(); i++) {
     Node currentChild = children.item(i);
     if (currentChild.getNodeType() == Node.ELEMENT_NODE
         && ((Element) currentChild).getTagName().equals(tagName)) {
       goodChildren.add(currentChild);
     }
   }
   return goodChildren.iterator();
 }
 /**
  * Gets the child of the specified element having the specified unique name.
  * If there are more than one children elements with the same name and
  * exception is thrown.
  * 
  * @param element
  *          The parent element
  * @param tagName
  *          The name of the desired child
  * @return The named child.
  * 
  * @throws Exception
  *           Child was not found or was not unique.
  */
 public static Element getUniqueChild(Element element, String tagName) throws Exception {
   Iterator goodChildren = getChildrenByTagName(element, tagName);
   if (goodChildren != null && goodChildren.hasNext()) {
     Element child = (Element) goodChildren.next();
     if (goodChildren.hasNext()) {
       throw new Exception("expected only one " + tagName + " tag");
     }
     return child;
   } else {
     throw new Exception("expected one " + tagName + " tag");
   }
 }
 /**
  * Gets the child of the specified element having the specified name. If the
  * child with this name doesn"t exist then null is returned instead.
  * 
  * @param element
  *          the parent element
  * @param tagName
  *          the name of the desired child
  * @return either the named child or null
  * @throws Exception
  */
 public static Element getOptionalChild(Element element, String tagName) throws Exception {
   return getOptionalChild(element, tagName, null);
 }
 /**
  * Gets the child of the specified element having the specified name. If the
  * child with this name doesn"t exist then the supplied default element is
  * returned instead.
  * 
  * @param element
  *          the parent element
  * @param tagName
  *          the name of the desired child
  * @param defaultElement
  *          the element to return if the child doesn"t exist
  * @return either the named child or the supplied default
  * @throws Exception
  */
 public static Element getOptionalChild(Element element, String tagName, Element defaultElement)
     throws Exception {
   Iterator goodChildren = getChildrenByTagName(element, tagName);
   if (goodChildren != null && goodChildren.hasNext()) {
     Element child = (Element) goodChildren.next();
     if (goodChildren.hasNext()) {
       throw new Exception("expected only one " + tagName + " tag");
     }
     return child;
   } else {
     return defaultElement;
   }
 }
 /**
  * Get the content of the given element.
  * 
  * @param element
  *          The element to get the content for.
  * @return The content of the element or null.
  * @throws Exception
  */
 public static String getElementContent(final Element element) throws Exception {
   return getElementContent(element, null);
 }
 /**
  * Get the content of the given element.
  * 
  * @param element
  *          The element to get the content for.
  * @param defaultStr
  *          The default to return when there is no content.
  * @return The content of the element or the default.
  * @throws Exception
  */
 public static String getElementContent(Element element, String defaultStr) throws Exception {
   if (element == null)
     return defaultStr;
   NodeList children = element.getChildNodes();
   String result = "";
   for (int i = 0; i < children.getLength(); i++) {
     if (children.item(i).getNodeType() == Node.TEXT_NODE
         || children.item(i).getNodeType() == Node.CDATA_SECTION_NODE) {
       result += children.item(i).getNodeValue();
     } else if (children.item(i).getNodeType() == Node.ruMENT_NODE) {
       // Ignore comment nodes
     }
   }
   return result.trim();
 }
 /**
  * Macro to get the content of a unique child element.
  * 
  * @param element
  *          The parent element.
  * @param tagName
  *          The name of the desired child.
  * @return The element content or null.
  * @throws Exception
  */
 public static String getUniqueChildContent(Element element, String tagName) throws Exception {
   return getElementContent(getUniqueChild(element, tagName));
 }
 /**
  * Macro to get the content of an optional child element.
  * 
  * @param element
  *          The parent element.
  * @param tagName
  *          The name of the desired child.
  * @return The element content or null.
  * @throws Exception
  */
 public static String getOptionalChildContent(Element element, String tagName) throws Exception {
   return getElementContent(getOptionalChild(element, tagName));
 }
 public static boolean getOptionalChildBooleanContent(Element element, String name)
     throws Exception {
   Element child = getOptionalChild(element, name);
   if (child != null) {
     String value = getElementContent(child).toLowerCase();
     return value.equals("true") || value.equals("yes");
   }
   return false;
 }

}


 </source>
   
  
 
  



Get the first child of the specified type.

   <source lang="java">
 

import org.w3c.dom.Node; public class Utils {

 /**
  * Get the first child of the specified type.
  * 
  * @param parent
  * @param type
  * @return
  */
 public static Node getChild(Node parent, int type) {
     Node n = parent.getFirstChild();
     while (n != null && type != n.getNodeType()) {
         n = n.getNextSibling();
     }
     if (n == null) {
         return null;
     }
     return n;
 }

}


 </source>
   
  
 
  



Get the first child"s content ( ie it"s included TEXT node ).

   <source lang="java">
 

import org.w3c.dom.Node; /**

*  
*
* @author Costin Manolache
*/

public class Main {

 /** Get the first child"s content ( ie it"s included TEXT node ).
  */
 public static String getChildContent( Node parent, String name ) {
     Node first=parent.getFirstChild();
     if( first==null ) return null;
     for (Node node = first; node != null;
          node = node.getNextSibling()) {
         //System.out.println("getNode: " + name + " " + node.getNodeName());
         if( name.equals( node.getNodeName() ) ) {
             return getContent( node );
         }
     }
     return null;
 }
 /** Get the trimed text content of a node or null if there is no text
  */
 public static String getContent(Node n ) {
     if( n==null ) return null;
     Node n1=getChild(n, Node.TEXT_NODE);
     if( n1==null ) return null;
     String s1=n1.getNodeValue();
     return s1.trim();
 }
 /** Get the first direct child with a given type
  */
 public static Node getChild( Node parent, int type ) {
     Node n=parent.getFirstChild();
     while( n!=null && type != n.getNodeType() ) {
         n=n.getNextSibling();
     }
     if( n==null ) return null;
     return n;
 }

}


 </source>
   
  
 
  



Get the first direct child with a given type

   <source lang="java">
 

import org.w3c.dom.Node; /**

*  
*
* @author Costin Manolache
*/

public class Main {

 /** Get the first direct child with a given type
  */
 public static Node getChild( Node parent, int type ) {
     Node n=parent.getFirstChild();
     while( n!=null && type != n.getNodeType() ) {
         n=n.getNextSibling();
     }
     if( n==null ) return null;
     return n;
 }

}


 </source>
   
  
 
  



Get this Document"s root node

   <source lang="java">
  

import org.w3c.dom.Document; import org.w3c.dom.Element;

public class Main {

 // return this Document"s root node
 public static Element getRoot(Document doc) {
     return doc.getDocumentElement();
 } // getRoot(Document(:  Element
 

}


 </source>
   
  
 
  



Manipulate w3c DOM trees

   <source lang="java">
  

// // Copyright 2007 Requea. // ------------------------------------------------------------------------ // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //

import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.util.Stack; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.CDATASection; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException;

/**

* Utilities to manipulate w3c DOM trees.
* @author Pierre Dubois
*/

public class XMLUtils {

   private static DocumentBuilderFactory fDocumentFactory;
   private static Stack fParsersPool = new Stack();
   /**
    * Public Id and the Resource path (of the cached copy) 
    * of the DTDs for tag library descriptors. 
    */
   public static final String TAGLIB_DTD_PUBLIC_ID_11 = 
 "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN";
   public static final String TAGLIB_DTD_RESOURCE_PATH_11 = 
 "/javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd";
   public static final String TAGLIB_DTD_PUBLIC_ID_12 = 
 "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN";
   public static final String TAGLIB_DTD_RESOURCE_PATH_12 = 
 "/javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd";
   /**
    * Public Id and the Resource path (of the cached copy) 
    * of the DTDs for web application deployment descriptors
    */
   public static final String WEBAPP_DTD_PUBLIC_ID_22 = 
 "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN";
   public static final String WEBAPP_DTD_RESOURCE_PATH_22 = 
 "/javax/servlet/resources/web-app_2_2.dtd";
   public static final String WEBAPP_DTD_PUBLIC_ID_23 = 
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN";
   public static final String WEBAPP_DTD_RESOURCE_PATH_23 = 
 "/javax/servlet/resources/web-app_2_3.dtd";
   /**
    * List of the Public IDs that we cache, and their
    * associated location. This is used by 
    * an EntityResolver to return the location of the
    * cached copy of a DTD.
    */
   public static final String[] CACHED_DTD_PUBLIC_IDS = {
 TAGLIB_DTD_PUBLIC_ID_11,
 TAGLIB_DTD_PUBLIC_ID_12,
 WEBAPP_DTD_PUBLIC_ID_22,
 WEBAPP_DTD_PUBLIC_ID_23,
   };
   public static final String[] CACHED_DTD_RESOURCE_PATHS = {
 TAGLIB_DTD_RESOURCE_PATH_11,
 TAGLIB_DTD_RESOURCE_PATH_12,
 WEBAPP_DTD_RESOURCE_PATH_22,
 WEBAPP_DTD_RESOURCE_PATH_23,
   };
   private static synchronized void initFactory() {
     if(fDocumentFactory != null) 
       return;
     
     fDocumentFactory =
           DocumentBuilderFactory.newInstance();
     fDocumentFactory.setNamespaceAware(true);
     fDocumentFactory.setIgnoringElementContentWhitespace(true);
     fDocumentFactory.setValidating(false);
   }
   
   public static synchronized DocumentBuilder getParser() throws ParserConfigurationException {
     if(fParsersPool.isEmpty()) {
       // create a new parser
       initFactory();
       DocumentBuilder builder = fDocumentFactory.newDocumentBuilder();
           builder.setEntityResolver(entityResolver);
       return builder;
     } else {
       return (DocumentBuilder)fParsersPool.pop();
     }
   }
   public static synchronized void releaseParser(DocumentBuilder parser) {
     if(parser != null)
         fParsersPool.push(parser);
   }
   
   /**
    * Parse an xml document as an imput stream.
    * @param is
    * @return
    * @throws XMLException
    */
   public static Document parse(InputStream is) {
     DocumentBuilder builder = null;
     try {
       builder = getParser();
         // parse the document
             Document doc = builder.parse(is);
             return doc;
       } catch (Exception e) {
           
       } finally {
       releaseParser(builder);
       }
   }
   /**
    * Parses an xml document as a string.
    * @param xml
    * @return
    * @throws XMLException
    */
   public static Document parse(String xml) {
     DocumentBuilder builder = null;
     try {
       builder = getParser();
         // parse the document
         try {
             InputStream is = new ByteArrayInputStream(xml.getBytes());
             Document doc = builder.parse(is);
             return doc;
         } catch (SAXException e) {    
             
         } catch (IOException e) {
              
         }
       } catch (ParserConfigurationException e) {
           
       } finally {
       releaseParser(builder);
     }
   }
   /**
    * Creates a new and empty document.
    * @return
    */
   public static Document newDocument() {
     DocumentBuilder builder = null;
     try {
       builder = getParser();
           return builder.newDocument();
     } catch (ParserConfigurationException e) {
         throw new RuntimeException(e);
     } finally {
     releaseParser(builder);
   }
   }
   /**
    * Creates a new document with a document root element.
    * @param name
    * @return
    */
   public static Element newElement(String name) {
     DocumentBuilder builder = null;
     try {
       builder = getParser();
           Document doc = builder.newDocument();
           Element el = doc.createElement(name);
           doc.appendChild(el);
           return el;
     } catch (ParserConfigurationException e) {
         throw new RuntimeException(e);
     } finally {
     releaseParser(builder);
   }
   }
   /**
    * Serialize an element to a string.
    * @param element
    * @return
    * @throws XMLException 
    */
   public static String ElementToString(Element element) {
       return privateElementToString(element, true, true);
   }
   public static String ElementToString(Element element, boolean pretty) {
       return privateElementToString(element, true, pretty);
   }
   /**
    * Serialize a document to a string
    * @param doc
    * @return
    */
   public static String DocumentToString(Document doc)  {
       return privateElementToString(doc.getDocumentElement(), false, true);
   }
   public static String DocumentToString(Document doc, boolean pretty) {
       return privateElementToString(doc.getDocumentElement(), false, pretty);
   }
   /**
    * Get the first child element to match a given name. 
    * Look for a child element in the same namespace as the parent.
    * 
    * @param parent
    * @param name
    * @return
    */
   public static Element getChild(Element parent, String name) {
     Element child = getFirstChild(parent);
     while(child != null) {
         String tagName = child.getTagName(); 
       if(tagName != null && tagName.equals(name)) {
         return child;
       }
       if(child.getPrefix() != null && child.getPrefix().equals(parent.getPrefix()) && child.getLocalName() != null && child.getLocalName().equals(name)) {
         return child;
       }
       child = getNext(child);
     }
     return child;
   }
   /**
    * Get the first child element to match a given name. 
    * Look for a child element in the same namespace as the parent.
    * 
    * @param parent
    * @param name
    * @return
    */
   public static Element getChild(Element parent, String ns, String name) {
     Element child = getFirstChild(parent);
     while(child != null) {
       if(child.getLocalName().equals(name)) {
         if(ns == null && child.getNamespaceURI() == null) {
           return child;
         } else if(ns != null && ns.equals(child.getNamespaceURI())) {
             return child;
         }
       }
       child = getNext(child);
     }
     return child;
   }
   /**
    * Get the first child element of an element.
    * @param el
    * @return
    */
   public static Element getFirstChild(Element el) {
     if(el == null) {
       return null;
     }
       NodeList lst = el.getChildNodes();
       int len = lst.getLength();
       for (int i = 0; i < len; i++) {
           Node n = lst.item(i);
           if (n instanceof Element)
               return (Element) n;
       }
       return null;
   }
   
   /**
    * Get the next sibling element of a given element.
    * @param el
    * @return
    */
   public static Element getNext(Element el) {
       Node n = el.getNextSibling();
       while (n != null && !(n instanceof Element)) {
           // get the next one
           n = n.getNextSibling();
       }
       if (n instanceof Element) {
           return (Element) n;
       }
       // else, nothing to return
       return null;
   }
   /**
    * Get the next sibling element of a given element.
    * @param el
    * @return
    */
   public static Element getNextSibling(Element el) {
     String tagName = el.getTagName();
     if(tagName == null) {
       return null;
     }
     Node n = el.getNextSibling();
       while (n != null && (
           !(n instanceof Element) || 
           !tagName.equals(((Element)n).getTagName()))) {
           // get the next one
           n = n.getNextSibling();
       }
       if (n instanceof Element) {
           return (Element) n;
       } else {
         // else, nothing to return
         return null;
       }
   }
   /**
    * Get the previous sibling element of a given element.
    * @param el
    * @return
    */
   public static Element getPrevious(Element el) {
       Node n = el.getPreviousSibling();
       while (n != null && !(n instanceof Element)) {
           // get the next one
           n = n.getPreviousSibling();
       }
       if (n instanceof Element) {
           return (Element) n;
       } else {
         // else, nothing to return
         return null;
       }
   }
   /**
    * Get the previous sibling element of a given element.
    * @param el
    * @return
    */
   public static Element getPreviousSibling(Element el) {
       Node n = el.getPreviousSibling();
       while (n != null && ( 
           !(n instanceof Element) || 
           !el.getTagName().equals(((Element)n).getTagName()))) {
           // get the next one
           n = n.getPreviousSibling();
       }
       if (n instanceof Element) {
           return (Element) n;
       } else {
         // else, nothing to return
         return null;
       }
   }
   /**
    * Returns the text value of an element.
    * @param el
    * @return
    */
   public static String getTextValue(Element el) {
       StringBuffer b = new StringBuffer();
       // retrieve the text node child
       NodeList nl = el.getChildNodes();
       int len = nl.getLength();
       for (int i = 0; i < len; i++) {
           Node n = nl.item(i);
           if (n instanceof Text) {
               Text t = (Text) n;
               b.append(t.getData());
           }
       }
       // trim the result, ignoring the first spaces and cariage return
       int iFirst =0;
       for(; iFirst<b.length(); iFirst++) {
         char c = b.charAt(iFirst);
         if(c != " " && c != "\r" && c != "\n" && c != "\t") {
           break;
         }
       }
       // start by the end as well
       int iLast = b.length()-1; 
       for(; iLast>=0; iLast--) {
         char c = b.charAt(iLast);
         if(c != " " && c != "\r" && c != "\n" && c != "\t") {
           break;
         }
       }
       return b.substring(iFirst, iLast+1);
   }
   /**
    * Get the text value of a child element with a given name. 
    * @param parent
    * @param name
    * @return
    */
   public static String getChildText(Element parent, String name) {
       Element child = getChild(parent, name);
       if (child != null) {
           return getTextValue(child);
       }
       return null;
   }
   /**
    * Get the text value of a child element with a given name. 
    * @param parent
    * @param name
    * @return
    */
   public static String getChildText(Element parent, String ns, String name) {
       Element child = getChild(parent, ns, name);
       if (child != null) {
           return getTextValue(child);
       }
       return null;
   }
   /**
    * Adds an element as a child of a given element. 
    * The child is created with the same namespace as the parent. 
    * @param parent
    * @param name
    * @return
    */
   public static Element addElement(Element parent, String name) {
       Document doc = parent.getOwnerDocument();
       String qname;
       if(parent.getPrefix() != null) {
           qname = parent.getPrefix() + ":" + name;
       } else {
           qname = name;
       }
       Element child = doc.createElementNS(parent.getNamespaceURI(), qname);
       parent.appendChild(child);
       return child;
   }
   /**
    * Adds an element as a child of a given element and sets the text value.
    * The child is created with the same namespace as the parent. 
    * 
    * @param parent
    * @param name
    * @param textValue
    * @return
    */
   public static Element addElement(
       Element parent,
       String name,
       String textValue) {
       
       Element child = addElement(parent, name);
       // create a text node
       if(textValue == null) {
         textValue = "";
       }
       Text txt = child.getOwnerDocument().createTextNode(textValue);
       child.appendChild(txt);
       return child;
   }
   /**
    * Sets the text value for a given element.
    * @param el
    * @param value
    */
   public static void setText(Element el, String value) {
       // remove the children if already exist
       while (el.getFirstChild() != null) {
           el.removeChild(el.getFirstChild());
       }
       if(value == null) {
         value = "";
       }
       Text txt = el.getOwnerDocument().createTextNode(value);
       el.appendChild(txt);
   }
   /**
    * Sets the text value for a given element as a CDATA section
    * @param el
    * @param value
    */
   public static void setCDATA(Element el, String value) {
       // remove the children if already exist
       while (el.getFirstChild() != null) {
           el.removeChild(el.getFirstChild());
       }
       if(value == null) {
         value = "";
       }
       CDATASection txt = el.getOwnerDocument().createCDATASection(value);
       el.appendChild(txt);
   }
   /**
    * Retrieve the namespace for a given prefix. 
    * Does a lookup into the parent hierarchy.
    * @param el
    * @param prefix
    * @return
    */
   public static String getNamespace(Element el, String prefix) {
       Element parent = el;
       while (parent != null) {
           String ns = parent.getAttribute("xmlns:" + prefix);
           if (ns != null && ns.length() > 0) {
               return ns;
           }
           // get the parent
           Node n = parent.getParentNode();
           if (n instanceof Element) {
               parent = (Element) n;
           } else {
               parent = null;
           }
       }
       // nothing found
       return null;
   }
   /*
    * serialize an element to a string.
    */
   private static String privateElementToString(
       Element element,
       boolean omitXMLDecl,
   boolean pretty)  {
     try {
       Source source = new DOMSource(element);
     StringWriter out = new StringWriter();
     
     StreamResult result = new StreamResult(out);
     Transformer xformer = TransformerFactory.newInstance().newTransformer();
     xformer.setOutputProperty("indent", "yes");
     xformer.transform(source, result);
     return out.toString();
     } catch(Exception e) {
      
     }
   }
   
 public static String getAttribute(Element el, String att) {
   String str = el.getAttribute(att);
   if(str == null || str.length() == 0) {
     return null;
   } else {
     return str;
   }
 }
 
   static EntityResolver entityResolver = new MyEntityResolver();
 static private class MyEntityResolver implements EntityResolver {
     public InputSource resolveEntity(String publicId, String systemId)
             throws SAXException {
         for (int i = 0; i < CACHED_DTD_PUBLIC_IDS.length; i++) {
             String cachedDtdPublicId = CACHED_DTD_PUBLIC_IDS[i];
             if (cachedDtdPublicId.equals(publicId)) {
                 String resourcePath = CACHED_DTD_RESOURCE_PATHS[i];
                 InputStream input = this.getClass().getResourceAsStream(
                         resourcePath);
                 if (input == null) {
                     throw new SAXException("file.not.found"+resourcePath);
                 }
                 InputSource isrc = new InputSource(input);
                 return isrc;
             }
         }
         return null;
     }
 }

}


 </source>
   
  
 
  



Print Tree node

   <source lang="java">
 

import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletResponse; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /*

* Copyright 2005 Joe Walker
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**

* 
* @author Abey Mullassery
* 
*/

public class Main {

 public static void printTree(Node doc) {
   if (doc == null) {
     System.out.println("Nothing to print!!");
     return;
   }
   try {
     System.out.println(doc.getNodeName() + "  " + doc.getNodeValue());
     NamedNodeMap cl = doc.getAttributes();
     for (int i = 0; i < cl.getLength(); i++) {
       Node node = cl.item(i);
       System.out.println(
         "\t" + node.getNodeName() + " ->" + node.getNodeValue());
     }
     NodeList nl = doc.getChildNodes();
     for (int i = 0; i < nl.getLength(); i++) {
       Node node = nl.item(i);
       printTree(node);
     }
   } catch (Throwable e) {
     System.out.println("Cannot print!! " + e.getMessage());
   }
 }

}


 </source>
   
  
 
  



Reading a DOM tree from XML document

   <source lang="java">
    

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; public class Main {

 public static void main(String[] argv) throws Exception {
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   DocumentBuilder loader = factory.newDocumentBuilder();
   Document document = loader.parse("sample.xml");
   Element tree = document.getDocumentElement();
 }

}



 </source>
   
  
 
  



Returns an iterator over the children of the given element with the given tag name

   <source lang="java">
  

import java.util.ArrayList; import java.util.Iterator; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /**

* A utility class to cover up the rough bits of xml parsing
* 
* @author 
* @version $Revision: 2787 $
*/

@SuppressWarnings("unchecked") public class XmlHelper {

 /**
  * Returns an iterator over the children of the given element with the given
  * tag name.
  * 
  * @param element
  *          The parent element
  * @param tagName
  *          The name of the desired child
  * @return An interator of children or null if element is null.
  */
 public static Iterator getChildrenByTagName(Element element, String tagName) {
   if (element == null)
     return null;
   // getElementsByTagName gives the corresponding elements in the whole
   // descendance. We want only children
   NodeList children = element.getChildNodes();
   ArrayList goodChildren = new ArrayList();
   for (int i = 0; i < children.getLength(); i++) {
     Node currentChild = children.item(i);
     if (currentChild.getNodeType() == Node.ELEMENT_NODE
         && ((Element) currentChild).getTagName().equals(tagName)) {
       goodChildren.add(currentChild);
     }
   }
   return goodChildren.iterator();
 }
 /**
  * Gets the child of the specified element having the specified unique name.
  * If there are more than one children elements with the same name and
  * exception is thrown.
  * 
  * @param element
  *          The parent element
  * @param tagName
  *          The name of the desired child
  * @return The named child.
  * 
  * @throws Exception
  *           Child was not found or was not unique.
  */
 public static Element getUniqueChild(Element element, String tagName) throws Exception {
   Iterator goodChildren = getChildrenByTagName(element, tagName);
   if (goodChildren != null && goodChildren.hasNext()) {
     Element child = (Element) goodChildren.next();
     if (goodChildren.hasNext()) {
       throw new Exception("expected only one " + tagName + " tag");
     }
     return child;
   } else {
     throw new Exception("expected one " + tagName + " tag");
   }
 }
 /**
  * Gets the child of the specified element having the specified name. If the
  * child with this name doesn"t exist then null is returned instead.
  * 
  * @param element
  *          the parent element
  * @param tagName
  *          the name of the desired child
  * @return either the named child or null
  * @throws Exception
  */
 public static Element getOptionalChild(Element element, String tagName) throws Exception {
   return getOptionalChild(element, tagName, null);
 }
 /**
  * Gets the child of the specified element having the specified name. If the
  * child with this name doesn"t exist then the supplied default element is
  * returned instead.
  * 
  * @param element
  *          the parent element
  * @param tagName
  *          the name of the desired child
  * @param defaultElement
  *          the element to return if the child doesn"t exist
  * @return either the named child or the supplied default
  * @throws Exception
  */
 public static Element getOptionalChild(Element element, String tagName, Element defaultElement)
     throws Exception {
   Iterator goodChildren = getChildrenByTagName(element, tagName);
   if (goodChildren != null && goodChildren.hasNext()) {
     Element child = (Element) goodChildren.next();
     if (goodChildren.hasNext()) {
       throw new Exception("expected only one " + tagName + " tag");
     }
     return child;
   } else {
     return defaultElement;
   }
 }
 /**
  * Get the content of the given element.
  * 
  * @param element
  *          The element to get the content for.
  * @return The content of the element or null.
  * @throws Exception
  */
 public static String getElementContent(final Element element) throws Exception {
   return getElementContent(element, null);
 }
 /**
  * Get the content of the given element.
  * 
  * @param element
  *          The element to get the content for.
  * @param defaultStr
  *          The default to return when there is no content.
  * @return The content of the element or the default.
  * @throws Exception
  */
 public static String getElementContent(Element element, String defaultStr) throws Exception {
   if (element == null)
     return defaultStr;
   NodeList children = element.getChildNodes();
   String result = "";
   for (int i = 0; i < children.getLength(); i++) {
     if (children.item(i).getNodeType() == Node.TEXT_NODE
         || children.item(i).getNodeType() == Node.CDATA_SECTION_NODE) {
       result += children.item(i).getNodeValue();
     } else if (children.item(i).getNodeType() == Node.ruMENT_NODE) {
       // Ignore comment nodes
     }
   }
   return result.trim();
 }
 /**
  * Macro to get the content of a unique child element.
  * 
  * @param element
  *          The parent element.
  * @param tagName
  *          The name of the desired child.
  * @return The element content or null.
  * @throws Exception
  */
 public static String getUniqueChildContent(Element element, String tagName) throws Exception {
   return getElementContent(getUniqueChild(element, tagName));
 }
 /**
  * Macro to get the content of an optional child element.
  * 
  * @param element
  *          The parent element.
  * @param tagName
  *          The name of the desired child.
  * @return The element content or null.
  * @throws Exception
  */
 public static String getOptionalChildContent(Element element, String tagName) throws Exception {
   return getElementContent(getOptionalChild(element, tagName));
 }
 public static boolean getOptionalChildBooleanContent(Element element, String name)
     throws Exception {
   Element child = getOptionalChild(element, name);
   if (child != null) {
     String value = getElementContent(child).toLowerCase();
     return value.equals("true") || value.equals("yes");
   }
   return false;
 }

}


 </source>
   
  
 
  



Returns the concatenated child text of the specified node.

   <source lang="java">
  

import org.w3c.dom.Element; import org.w3c.dom.Node; /*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

public class Main {

 /**
  * Returns the concatenated child text of the specified node.
  * This method only looks at the immediate children of type
  * Node.TEXT_NODE or the children of any child
  * node that is of type Node.CDATA_SECTION_NODE
  * for the concatenation.
  *
  * @param node The node to look at.
  */
 public static String getChildText(Node node) {
     
     // is there anything to do?
     if (node == null) {
         return null;
     }
     
     // concatenate children text
     StringBuffer str = new StringBuffer();
     Node child = node.getFirstChild();
     while (child != null) {
         short type = child.getNodeType();
         if (type == Node.TEXT_NODE) {
             str.append(child.getNodeValue());
         }
         else if (type == Node.CDATA_SECTION_NODE) {
             str.append(getChildText(child));
         }
         child = child.getNextSibling();
     }
     
     // return text value
     return str.toString();
     
 } // getChildText(Node):String

}


 </source>
   
  
 
  



Return the next sibling with a given name and type

   <source lang="java">
 

import org.w3c.dom.Node; public class Main {

 /** 
  */ 
 public static Node getNext( Node current, String name, int type) {
     Node first=current.getNextSibling();
     if( first==null ) return null;
     for (Node node = first; node != null;
          node = node.getNextSibling()) {
         
         if( type >= 0 && node.getNodeType() != type ) continue;
         //System.out.println("getNode: " + name + " " + node.getNodeName());
         if( name==null )
             return node;
         if( name.equals( node.getNodeName() ) ) {
             return node;
         }
     }
     return null;
 }

}


 </source>
   
  
 
  



Saving a DOM tree to XML file javax.xml.parsers (JAXP)

   <source lang="java">
    

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.sun.org.apache.xml.internal.serialize.XMLSerializer; public class Main {

 public static void main(String[] argv) throws Exception {
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   DocumentBuilder loader = factory.newDocumentBuilder();
   Document document = loader.newDocument();
   Element order = document.createElement("order");
   document.appendChild(order);
   XMLSerializer serializer = new XMLSerializer();
   serializer.setOutputCharStream(new java.io.FileWriter("order.xml"));
   serializer.serialize(document);
 }

}



 </source>
   
  
 
  



Search earlier siblings for a given node

   <source lang="java">
 

/**********************************************************************************

  • Copyright (c) 2003, 2004 The Regents of the University of Michigan, Trustees of Indiana University,
  • Board of Trustees of the Leland Stanford, Jr., University, and The MIT Corporation
  • Licensed under the Educational Community License Version 1.0 (the "License");
  • By obtaining, using and/or copying this Original Work, you agree that you have read,
  • understand, and will comply with the terms and conditions of the Educational Community License.
  • You may obtain a copy of the License at:
  • http://cvs.sakaiproject.org/licenses/license_1_0.html
  • THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  • INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
  • AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  • DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  • FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                                                                                                                                                                    • /

import org.w3c.dom.Node; public class Utils {

 /**
  * Search earlier siblings for a given node
  * @param currentNode Starting point for our search
  * @param tagName Node name to look up
  * @return matching Node (null if none)
  */
 public static Node getPreviousSiblingByName(Node currentNode, String tagName) {
   Node node = currentNode.getPreviousSibling();
   while ((node != null) && (!node.getNodeName().equals(tagName))) {
     node = node.getPreviousSibling();
   }
   return node;
 }

}


 </source>
   
  
 
  



Search for a named child of a given node

   <source lang="java">
 

import org.w3c.dom.Node; public class Utils {

 /**
  * Search for a named child of a given node
  * @param currentNode Starting point for our search
  * @param tagName Node name to look up
  * @return matching Node (null if none)
  */
 public static Node getChildSiblingByName(Node currentNode, String tagName) {
   Node node = currentNode.getFirstChild();
   while ((node != null) && (!node.getNodeName().equals(tagName))) {
     node = node.getNextSibling();
   }
   return node;
 }

}


 </source>
   
  
 
  



Search our next siblings for a given node

   <source lang="java">
 

/**********************************************************************************

  • Copyright (c) 2003, 2004 The Regents of the University of Michigan, Trustees of Indiana University,
  • Board of Trustees of the Leland Stanford, Jr., University, and The MIT Corporation
  • Licensed under the Educational Community License Version 1.0 (the "License");
  • By obtaining, using and/or copying this Original Work, you agree that you have read,
  • understand, and will comply with the terms and conditions of the Educational Community License.
  • You may obtain a copy of the License at:
  • http://cvs.sakaiproject.org/licenses/license_1_0.html
  • THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  • INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
  • AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  • DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  • FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                                                                                                                                                                    • /

import org.w3c.dom.Node; public class Utils {

 /**
  * Search our next siblings for a given node
  * @param currentNode Starting point for our search
  * @param tagName Node name to look up
  * @return matching Node (null if none)
  */
 public static Node getNextSiblingByName(Node currentNode, String tagName) {
   Node node = currentNode.getNextSibling();
   while ((node != null) && (!node.getNodeName().equals(tagName))) {
     node = node.getNextSibling();
   }
   return node;
 }

}


 </source>
   
  
 
  



Search up the tree for a given node

   <source lang="java">
 

/**********************************************************************************

  • Copyright (c) 2003, 2004 The Regents of the University of Michigan, Trustees of Indiana University,
  • Board of Trustees of the Leland Stanford, Jr., University, and The MIT Corporation
  • Licensed under the Educational Community License Version 1.0 (the "License");
  • By obtaining, using and/or copying this Original Work, you agree that you have read,
  • understand, and will comply with the terms and conditions of the Educational Community License.
  • You may obtain a copy of the License at:
  • http://cvs.sakaiproject.org/licenses/license_1_0.html
  • THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  • INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
  • AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  • DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  • FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                                                                                                                                                                    • /

import org.w3c.dom.Node; public class Utils {

 /**
  * Search up the tree for a given node
  * @param currentNode Starting point for our search
  * @param tagName Node name to look up
  * @return matching Node (null if none)
  */
 public static Node getPreviousNodeByName(Node currentNode, String tagName) {
   Node node = currentNode.getParentNode();
   while ((node != null) && (!node.getNodeName().equals(tagName))) {
     node = node.getParentNode();
   }
   return node;
 }

}


 </source>
   
  
 
  



Traverse a DOM tree in order to get information about the document.

   <source lang="java">
  

/*

* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
* 
*      http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.io.PrintWriter; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.Text; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; import org.xml.sax.SAXParseException; /**

* A sample DOM counter. This sample program illustrates how to
* traverse a DOM tree in order to get information about the document.
* The output of this program shows the time and count of elements,
* attributes, ignorable whitespaces, and characters appearing in
* the document. Three times are shown: the parse time, the first
* traversal of the document, and the second traversal of the tree.
*

* This class is useful as a "poor-man"s" performance tester to * compare the speed and accuracy of various DOM parsers. However, * it is important to note that the first parse time of a parser * will include both VM class load time and parser initialization * that would not be present in subsequent parses with the same * file. * <p> * Note: The results produced by this program * should never be accepted as true performance measurements. * * @author Andy Clark, IBM * * @version $Id: Counter.java 447683 2006-09-19 02:36:31Z mrglavas $ */ public class Counter { // // Constants // // feature ids /** Namespaces feature id (http://xml.org/sax/features/namespaces). */ protected static final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces"; /** Validation feature id (http://xml.org/sax/features/validation). */ protected static final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation"; /** Schema validation feature id (http://apache.org/xml/features/validation/schema). */ protected static final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema"; /** Schema full checking feature id (http://apache.org/xml/features/validation/schema-full-checking). */ protected static final String SCHEMA_FULL_CHECKING_FEATURE_ID = "http://apache.org/xml/features/validation/schema-full-checking"; /** Honour all schema locations feature id (http://apache.org/xml/features/honour-all-schemaLocations). */ protected static final String HONOUR_ALL_SCHEMA_LOCATIONS_ID = "http://apache.org/xml/features/honour-all-schemaLocations"; /** Validate schema annotations feature id (http://apache.org/xml/features/validate-annotations). */ protected static final String VALIDATE_ANNOTATIONS_ID = "http://apache.org/xml/features/validate-annotations"; /** Dynamic validation feature id (http://apache.org/xml/features/validation/dynamic). */ protected static final String DYNAMIC_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/dynamic"; /** XInclude feature id (http://apache.org/xml/features/xinclude). */ protected static final String XINCLUDE_FEATURE_ID = "http://apache.org/xml/features/xinclude"; /** XInclude fixup base URIs feature id (http://apache.org/xml/features/xinclude/fixup-base-uris). */ protected static final String XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID = "http://apache.org/xml/features/xinclude/fixup-base-uris"; /** XInclude fixup language feature id (http://apache.org/xml/features/xinclude/fixup-language). */ protected static final String XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID = "http://apache.org/xml/features/xinclude/fixup-language"; // default settings /** Default parser name (dom.wrappers.Xerces). */ protected static final String DEFAULT_PARSER_NAME = "dom.wrappers.Xerces"; /** Default repetition (1). */ protected static final int DEFAULT_REPETITION = 1; /** Default namespaces support (true). */ protected static final boolean DEFAULT_NAMESPACES = true; /** Default validation support (false). */ protected static final boolean DEFAULT_VALIDATION = false; /** Default Schema validation support (false). */ protected static final boolean DEFAULT_SCHEMA_VALIDATION = false; /** Default Schema full checking support (false). */ protected static final boolean DEFAULT_SCHEMA_FULL_CHECKING = false; /** Default honour all schema locations (false). */ protected static final boolean DEFAULT_HONOUR_ALL_SCHEMA_LOCATIONS = false; /** Default validate schema annotations (false). */ protected static final boolean DEFAULT_VALIDATE_ANNOTATIONS = false; /** Default dynamic validation support (false). */ protected static final boolean DEFAULT_DYNAMIC_VALIDATION = false; /** Default XInclude processing support (false). */ protected static final boolean DEFAULT_XINCLUDE = false; /** Default XInclude fixup base URIs support (true). */ protected static final boolean DEFAULT_XINCLUDE_FIXUP_BASE_URIS = true; /** Default XInclude fixup language support (true). */ protected static final boolean DEFAULT_XINCLUDE_FIXUP_LANGUAGE = true; // // Data // /** Number of elements. */ protected long fElements; /** Number of attributes. */ protected long fAttributes; /** Number of characters. */ protected long fCharacters; /** Number of ignorable whitespace characters. */ protected long fIgnorableWhitespace; /** Document information. */ protected ParserWrapper.DocumentInfo fDocumentInfo; // // Public methods // /** Sets the parser wrapper. */ public void setDocumentInfo(ParserWrapper.DocumentInfo documentInfo) { fDocumentInfo = documentInfo; } // setDocumentInfo(ParserWrapper.DocumentInfo) /** Traverses the specified node, recursively. */ public void count(Node node) { // is there anything to do? if (node == null) { return; } int type = node.getNodeType(); switch (type) { case Node.DOCUMENT_NODE: { fElements = 0; fAttributes = 0; fCharacters = 0; fIgnorableWhitespace = 0; Document document = (Document)node; count(document.getDocumentElement()); break; } case Node.ELEMENT_NODE: { fElements++; NamedNodeMap attrs = node.getAttributes(); if (attrs != null) { fAttributes += attrs.getLength(); } // drop through to entity reference } case Node.ENTITY_REFERENCE_NODE: { Node child = node.getFirstChild(); while (child != null) { count(child); child = child.getNextSibling(); } break; } case Node.CDATA_SECTION_NODE: { fCharacters += ((Text)node).getLength(); break; } case Node.TEXT_NODE: { if (fDocumentInfo != null) { Text text = (Text)node; int length = text.getLength(); if (fDocumentInfo.isIgnorableWhitespace(text)) { fIgnorableWhitespace += length; } else { fCharacters += length; } } break; } } } // count(Node) /** Prints the results. */ public void printResults(PrintWriter out, String uri, long parse, long traverse1, long traverse2, int repetition) { // filename.xml: 631/200/100 ms (4 elems, 0 attrs, 78 spaces, 0 chars) out.print(uri); out.print(": "); if (repetition == 1) { out.print(parse); } else { out.print(parse); out.print("/"); out.print(repetition); out.print("="); out.print(parse/repetition); } out.print(";"); out.print(traverse1); out.print(";"); out.print(traverse2); out.print(" ms ("); out.print(fElements); out.print(" elems, "); out.print(fAttributes); out.print(" attrs, "); out.print(fIgnorableWhitespace); out.print(" spaces, "); out.print(fCharacters); out.print(" chars)"); out.println(); out.flush(); } // printResults(PrintWriter,String,long,long,long) // // MAIN // /** Main program entry point. */ public static void main(String argv[]) { // is there anything to do? if (argv.length == 0) { printUsage(); System.exit(1); } // variables Counter counter = new Counter(); PrintWriter out = new PrintWriter(System.out); ParserWrapper parser = null; int repetition = DEFAULT_REPETITION; boolean namespaces = DEFAULT_NAMESPACES; boolean validation = DEFAULT_VALIDATION; boolean schemaValidation = DEFAULT_SCHEMA_VALIDATION; boolean schemaFullChecking = DEFAULT_SCHEMA_FULL_CHECKING; boolean honourAllSchemaLocations = DEFAULT_HONOUR_ALL_SCHEMA_LOCATIONS; boolean validateAnnotations = DEFAULT_VALIDATE_ANNOTATIONS; boolean dynamicValidation = DEFAULT_DYNAMIC_VALIDATION; boolean xincludeProcessing = DEFAULT_XINCLUDE; boolean xincludeFixupBaseURIs = DEFAULT_XINCLUDE_FIXUP_BASE_URIS; boolean xincludeFixupLanguage = DEFAULT_XINCLUDE_FIXUP_LANGUAGE; // process arguments for (int i = 0; i < argv.length; i++) { String arg = argv[i]; if (arg.startsWith("-")) { String option = arg.substring(1); if (option.equals("p")) { // get parser name if (++i == argv.length) { System.err.println("error: Missing argument to -p option."); } String parserName = argv[i]; // create parser try { parser = (ParserWrapper)Class.forName(parserName).newInstance(); } catch (Exception e) { parser = null; System.err.println("error: Unable to instantiate parser ("+parserName+")"); } continue; } if (option.equals("x")) { if (++i == argv.length) { System.err.println("error: Missing argument to -x option."); continue; } String number = argv[i]; try { int value = Integer.parseInt(number); if (value < 1) { System.err.println("error: Repetition must be at least 1."); continue; } repetition = value; } catch (NumberFormatException e) { System.err.println("error: invalid number ("+number+")."); } continue; } if (option.equalsIgnoreCase("n")) { namespaces = option.equals("n"); continue; } if (option.equalsIgnoreCase("v")) { validation = option.equals("v"); continue; } if (option.equalsIgnoreCase("s")) { schemaValidation = option.equals("s"); continue; } if (option.equalsIgnoreCase("f")) { schemaFullChecking = option.equals("f"); continue; } if (option.equalsIgnoreCase("hs")) { honourAllSchemaLocations = option.equals("hs"); continue; } if (option.equalsIgnoreCase("va")) { validateAnnotations = option.equals("va"); continue; } if (option.equalsIgnoreCase("dv")) { dynamicValidation = option.equals("dv"); continue; } if (option.equalsIgnoreCase("xi")) { xincludeProcessing = option.equals("xi"); continue; } if (option.equalsIgnoreCase("xb")) { xincludeFixupBaseURIs = option.equals("xb"); continue; } if (option.equalsIgnoreCase("xl")) { xincludeFixupLanguage = option.equals("xl"); continue; } if (option.equals("h")) { printUsage(); continue; } } // use default parser? if (parser == null) { // create parser try { parser = (ParserWrapper)Class.forName(DEFAULT_PARSER_NAME).newInstance(); } catch (Exception e) { System.err.println("error: Unable to instantiate parser ("+DEFAULT_PARSER_NAME+")"); continue; } } // set parser features try { parser.setFeature(NAMESPACES_FEATURE_ID, namespaces); } catch (SAXException e) { System.err.println("warning: Parser does not support feature ("+NAMESPACES_FEATURE_ID+")"); } try { parser.setFeature(VALIDATION_FEATURE_ID, validation); } catch (SAXException e) { System.err.println("warning: Parser does not support feature ("+VALIDATION_FEATURE_ID+")"); } try { parser.setFeature(SCHEMA_VALIDATION_FEATURE_ID, schemaValidation); } catch (SAXException e) { System.err.println("warning: Parser does not support feature ("+SCHEMA_VALIDATION_FEATURE_ID+")"); } try { parser.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, schemaFullChecking); } catch (SAXException e) { System.err.println("warning: Parser does not support feature ("+SCHEMA_FULL_CHECKING_FEATURE_ID+")"); } try { parser.setFeature(HONOUR_ALL_SCHEMA_LOCATIONS_ID, honourAllSchemaLocations); } catch (SAXException e) { System.err.println("warning: Parser does not support feature ("+HONOUR_ALL_SCHEMA_LOCATIONS_ID+")"); } try { parser.setFeature(VALIDATE_ANNOTATIONS_ID, validateAnnotations); } catch (SAXException e) { System.err.println("warning: Parser does not support feature ("+VALIDATE_ANNOTATIONS_ID+")"); } try { parser.setFeature(DYNAMIC_VALIDATION_FEATURE_ID, dynamicValidation); } catch (SAXException e) { System.err.println("warning: Parser does not support feature ("+DYNAMIC_VALIDATION_FEATURE_ID+")"); } try { parser.setFeature(XINCLUDE_FEATURE_ID, xincludeProcessing); } catch (SAXException e) { System.err.println("warning: Parser does not support feature ("+XINCLUDE_FEATURE_ID+")"); } try { parser.setFeature(XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID, xincludeFixupBaseURIs); } catch (SAXException e) { System.err.println("warning: Parser does not support feature ("+XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID+")"); } try { parser.setFeature(XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID, xincludeFixupLanguage); } catch (SAXException e) { System.err.println("warning: Parser does not support feature ("+XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID+")"); } // parse file try { long beforeParse = System.currentTimeMillis(); Document document = null; for (int j = 0; j < repetition; j++) { document = parser.parse(arg); } long afterParse = System.currentTimeMillis(); long parse = afterParse - beforeParse; ParserWrapper.DocumentInfo documentInfo = parser.getDocumentInfo(); counter.setDocumentInfo(documentInfo); long beforeTraverse1 = System.currentTimeMillis(); counter.count(document); long afterTraverse1 = System.currentTimeMillis(); long traverse1 = afterTraverse1 - beforeTraverse1; long beforeTraverse2 = System.currentTimeMillis(); counter.count(document); long afterTraverse2 = System.currentTimeMillis(); long traverse2 = afterTraverse2 - beforeTraverse2; counter.printResults(out, arg, parse, traverse1, traverse2, repetition); } catch (SAXParseException e) { // ignore } catch (Exception e) { System.err.println("error: Parse error occurred - "+e.getMessage()); Exception se = e; if (e instanceof SAXException) { se = ((SAXException)e).getException(); } if (se != null) se.printStackTrace(System.err); else e.printStackTrace(System.err); } } } // main(String[]) // // Private static methods // /** Prints the usage. */ private static void printUsage() { System.err.println("usage: java dom.Counter (options) uri ..."); System.err.println(); System.err.println("options:"); System.err.println(" -p name Select parser by name."); System.err.println(" -x number Select number of repetitions."); System.err.println(" -n | -N Turn on/off namespace processing."); System.err.println(" -v | -V Turn on/off validation."); System.err.println(" -s | -S Turn on/off Schema validation support."); System.err.println(" NOTE: Not supported by all parsers."); System.err.println(" -f | -F Turn on/off Schema full checking."); System.err.println(" NOTE: Requires use of -s and not supported by all parsers."); System.err.println(" -hs | -HS Turn on/off honouring of all schema locations."); System.err.println(" NOTE: Requires use of -s and not supported by all parsers."); System.err.println(" -va | -VA Turn on/off validation of schema annotations."); System.err.println(" NOTE: Requires use of -s and not supported by all parsers."); System.err.println(" -dv | -DV Turn on/off dynamic validation."); System.err.println(" NOTE: Not supported by all parsers."); System.err.println(" -xi | -XI Turn on/off XInclude processing."); System.err.println(" NOTE: Not supported by all parsers."); System.err.println(" -xb | -XB Turn on/off base URI fixup during XInclude processing."); System.err.println(" NOTE: Requires use of -xi and not supported by all parsers."); System.err.println(" -xl | -XL Turn on/off language fixup during XInclude processing."); System.err.println(" NOTE: Requires use of -xi and not supported by all parsers."); System.err.println(" -h This help screen."); System.err.println(); System.err.println("defaults:"); System.err.println(" Parser: "+DEFAULT_PARSER_NAME); System.err.println(" Repetition: "+DEFAULT_REPETITION); System.err.print(" Namespaces: "); System.err.println(DEFAULT_NAMESPACES ? "on" : "off"); System.err.print(" Validation: "); System.err.println(DEFAULT_VALIDATION ? "on" : "off"); System.err.print(" Schema: "); System.err.println(DEFAULT_SCHEMA_VALIDATION ? "on" : "off"); System.err.print(" Schema full checking: "); System.err.println(DEFAULT_SCHEMA_FULL_CHECKING ? "on" : "off"); System.err.print(" Honour all schema locations: "); System.err.println(DEFAULT_HONOUR_ALL_SCHEMA_LOCATIONS ? "on" : "off"); System.err.print(" Validate annotations: "); System.err.println(DEFAULT_VALIDATE_ANNOTATIONS ? "on" : "off"); System.err.print(" Dynamic: "); System.err.println(DEFAULT_DYNAMIC_VALIDATION ? "on" : "off"); System.err.print(" XInclude: "); System.err.println(DEFAULT_XINCLUDE ? "on" : "off"); System.err.print(" XInclude base URI fixup: "); System.err.println(DEFAULT_XINCLUDE_FIXUP_BASE_URIS ? "on" : "off"); System.err.print(" XInclude language fixup: "); System.err.println(DEFAULT_XINCLUDE_FIXUP_LANGUAGE ? "on" : "off"); } // printUsage() } // class DOMCount /** * Encapsulates a DOM parser. * * @version $Id: ParserWrapper.java 447683 2006-09-19 02:36:31Z mrglavas $ */ interface ParserWrapper { // // ParserWrapper methods // /** Parses the specified URI and returns the document. */ public Document parse(String uri) throws Exception; /** * Set the state of a feature. * * Set the state of any feature in a SAX2 parser. The parser * might not recognize the feature, and if it does recognize * it, it might not be able to fulfill the request. * * @param featureId The unique identifier (URI) of the feature. * @param state The requested state of the feature (true or false). * * @exception org.xml.sax.SAXNotRecognizedException If the * requested feature is not known. * @exception org.xml.sax.SAXNotSupportedException If the * requested feature is known, but the requested * state is not supported. * @exception org.xml.sax.SAXException If there is any other * problem fulfilling the request. */ public void setFeature(String featureId, boolean state) throws SAXNotRecognizedException, SAXNotSupportedException; /** Returns the document information. */ public DocumentInfo getDocumentInfo(); // // Interfaces // /** * This interface is here to query information about the document * implementation returned by the ParserWrapper#parse * method. * * @author Andy Clark, IBM */ public interface DocumentInfo { // // DocumentInfo methods // /** * Returns true if the specified text node is ignorable whitespace. */ public boolean isIgnorableWhitespace(Text text); } // interface DocumentInfo } // interface ParserWrapper </source>

Traverse a DOM tree in order to print a document that is parsed.

   <source lang="java">

/*

* 
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution, if
*    any, must include the following acknowlegement:
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowlegement may appear in the software itself,
*    if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
*    Foundation" must not be used to endorse or promote products derived
*    from this software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
*    nor may "Apache" appear in their names without prior written
*    permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS"" AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* 
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/

import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /**

* Traverse a DOM tree in order to print a document that is parsed.
*
* @author Andy Clark, IBM
* @author Thomas.Diesler@jboss.org
*/

@SuppressWarnings("unchecked") public class DOMWriter {

 // Print writer
 private PrintWriter out;
 // True, if canonical output
 private boolean canonical;
 // True, if pretty printing should be used
 private boolean prettyprint;
 // True, if the XML declaration should be written
 private boolean writeXMLDeclaration;
 // True, if whitespace should be ignored
 private boolean ignoreWhitespace;
 // Explicit character set encoding
 private String charsetName;
 // indent for the pretty printer
 private int prettyIndent;
 // True, if the XML declaration has been written
 private boolean wroteXMLDeclaration;
 // The node that started the write
 private Node rootNode;
 // True if we want namespace completion
 private boolean completeNamespaces = true;
 // The current default namespace
 private String currentDefaultNamespace;
 public DOMWriter(Writer w)
 {
   this.out = new PrintWriter(w);
 }
 public DOMWriter(Writer w, String charsetName)
 {
   this.out = new PrintWriter(w);
   this.charsetName = charsetName;
   this.writeXMLDeclaration = true;
 }
 public DOMWriter(OutputStream stream)
 {
   try
   {
     this.out = new PrintWriter(new OutputStreamWriter(stream, "UTF-8"));
   }
   catch (UnsupportedEncodingException e)
   {
     // ignore, UTF-8 should be available
   }
 }
 public DOMWriter(OutputStream stream, String charsetName)
 {
   try
   {
     this.out = new PrintWriter(new OutputStreamWriter(stream, charsetName));
     this.charsetName = charsetName;
     this.writeXMLDeclaration = true;
   }
   catch (UnsupportedEncodingException e)
   {
     throw new IllegalArgumentException("Unsupported encoding: " + charsetName);
   }
 }
 /**
  * Print a node with explicit prettyprinting.
  * The defaults for all other DOMWriter properties apply.
  *
  */
 public static String printNode(Node node, boolean prettyprint)
 {
   StringWriter strw = new StringWriter();
   new DOMWriter(strw).setPrettyprint(prettyprint).print(node);
   return strw.toString();
 }
 public boolean isCanonical()
 {
   return canonical;
 }
 /**
  * Set wheter entities should appear in their canonical form.
  * The default is false.
  */
 public DOMWriter setCanonical(boolean canonical)
 {
   this.canonical = canonical;
   return this;
 }
 public boolean isIgnoreWhitespace()
 {
   return ignoreWhitespace;
 }
 /**
  * Set whether whitespace should be ignored.
  * The default is false.
  */
 public DOMWriter setIgnoreWhitespace(boolean ignoreWhitespace)
 {
   this.ignoreWhitespace = ignoreWhitespace;
   return this;
 }
 /**
  * Set wheter subelements should have their namespaces completed.
  * Setting this to false may lead to invalid XML fragments.
  * The default is true.
  */
 public DOMWriter setCompleteNamespaces(boolean complete)
 {
   this.rupleteNamespaces = complete;
   return this;
 }
 public boolean isPrettyprint()
 {
   return prettyprint;
 }
 /**
  * Set wheter element should be indented.
  * The default is false.
  */
 public DOMWriter setPrettyprint(boolean prettyprint)
 {
   this.prettyprint = prettyprint;
   return this;
 }
 public boolean isWriteXMLDeclaration()
 {
   return writeXMLDeclaration;
 }
 /**
  * Set wheter the XML declaration should be written.
  * The default is false.
  */
 public DOMWriter setWriteXMLDeclaration(boolean flag)
 {
   this.writeXMLDeclaration = flag;
   return this;
 }
 public void print(Node node)
 {
   if (prettyprint && ignoreWhitespace)
     throw new IllegalStateException("Cannot pretty print and ignore whitespace");
   rootNode = node;
   printInternal(node, false);
 }
 private void printInternal(Node node, boolean indentEndMarker)
 {
   // is there anything to do?
   if (node == null)
   {
     return;
   }
   // JBAS-2117 - Don"t skip the DOCUMENT_NODE
   // if (node instanceof Document) node = ((Document)node).getDocumentElement();
   if (wroteXMLDeclaration == false && writeXMLDeclaration == true && canonical == false)
   {
     out.print("<?xml version="1.0"");
     if (charsetName != null)
       out.print(" encoding="" + charsetName + """);
     out.print("?>");
     if (prettyprint)
       out.println();
     wroteXMLDeclaration = true;
   }
   int type = node.getNodeType();
   boolean hasChildNodes = node.getChildNodes().getLength() > 0;
   String nodeName = node.getNodeName();
   switch (type)
   {
     // print document
     case Node.DOCUMENT_NODE:
     {
       NodeList children = node.getChildNodes();
       for (int iChild = 0; iChild < children.getLength(); iChild++)
       {
         printInternal(children.item(iChild), false);
       }
       out.flush();
       break;
     }
     // print element with attributes
     case Node.ELEMENT_NODE:
     {
       Element element = (Element)node;
       if (prettyprint)
       {
         for (int i = 0; i < prettyIndent; i++)
         {
           out.print(" ");
         }
         prettyIndent++;
       }
       out.print("<");
       out.print(nodeName);
       Map nsMap = new HashMap();
       String elPrefix = node.getPrefix();
       String elNamespaceURI = node.getNamespaceURI();
       if (elPrefix != null)
       {
         String nsURI = getNamespaceURI(elPrefix, element, rootNode);
         nsMap.put(elPrefix, nsURI);
       }
       Attr attrs[] = sortAttributes(node.getAttributes());
       for (int i = 0; i < attrs.length; i++)
       {
         Attr attr = attrs[i];
         String atPrefix = attr.getPrefix();
         String atName = attr.getNodeName();
         String atValue = normalize(attr.getNodeValue(), canonical);
         if (atName.equals("xmlns"))
           currentDefaultNamespace = atValue;
         if (atPrefix != null && !atPrefix.equals("xmlns") && !atPrefix.equals("xml"))
         {
           String nsURI = getNamespaceURI(atPrefix, element, rootNode);
           nsMap.put(atPrefix, nsURI);
           // xsi:type="ns1:SubType", xsi:type="xsd:string"
           if (atName.equals(atPrefix + ":type") && atValue.indexOf(":") > 0)
           {
             // xsi defined on the envelope
             if (nsURI == null)
               nsURI = getNamespaceURI(atPrefix, element, null);
             if ("http://www.w3.org/2001/XMLSchema-instance".equals(nsURI))
             {
               String typePrefix = atValue.substring(0, atValue.indexOf(":"));
               String typeURI = getNamespaceURI(typePrefix, element, rootNode);
               nsMap.put(typePrefix, typeURI);
             }
           }
         }
         out.print(" " + atName + "="" + atValue + """);
       }
       // Add namespace declaration for prefixes
       // that are defined further up the tree
       if (completeNamespaces)
       {
         Iterator itPrefix = nsMap.keySet().iterator();
         while (itPrefix.hasNext())
         {
           String prefix = (String)itPrefix.next();
           String nsURI = (String)nsMap.get(prefix);
           if (nsURI == null)
           {
             nsURI = getNamespaceURI(prefix, element, null);
             out.print(" xmlns:" + prefix + "="" + nsURI + """);
           }
         }
       }
       // The SAX ContentHandler will by default not add the namespace declaration
       // <Hello xmlns="http://somens">World</Hello>
       if (elPrefix == null && elNamespaceURI != null)
       {
         String defaultNamespace = element.getAttribute("xmlns");
         if (defaultNamespace.length() == 0 && !elNamespaceURI.equals(currentDefaultNamespace))
         {
           out.print(" xmlns="" + elNamespaceURI + """);
           currentDefaultNamespace = elNamespaceURI;
         }
       }
       if (hasChildNodes)
       {
         out.print(">");
       }
       // Find out if the end marker is indented
       indentEndMarker = isEndMarkerIndented(node);
       if (indentEndMarker)
       {
         out.print("\n");
       }
       NodeList childNodes = node.getChildNodes();
       int len = childNodes.getLength();
       for (int i = 0; i < len; i++)
       {
         Node childNode = childNodes.item(i);
         printInternal(childNode, false);
       }
       break;
     }
     // handle entity reference nodes
     case Node.ENTITY_REFERENCE_NODE:
     {
       if (canonical)
       {
         NodeList children = node.getChildNodes();
         if (children != null)
         {
           int len = children.getLength();
           for (int i = 0; i < len; i++)
           {
             printInternal(children.item(i), false);
           }
         }
       }
       else
       {
         out.print("&");
         out.print(nodeName);
         out.print(";");
       }
       break;
     }
     // print cdata sections
     case Node.CDATA_SECTION_NODE:
     {
       if (canonical)
       {
         out.print(normalize(node.getNodeValue(), canonical));
       }
       else
       {
         out.print("<![CDATA[");
         out.print(node.getNodeValue());
         out.print("]]>");
       }
       break;
     }
     // print text
     case Node.TEXT_NODE:
     {
       String text = normalize(node.getNodeValue(), canonical);
       if (text.trim().length() > 0)
       {
         out.print(text);
       }
       else if (prettyprint == false && ignoreWhitespace == false)
       {
         out.print(text);
       }
       break;
     }
     // print processing instruction
     case Node.PROCESSING_INSTRUCTION_NODE:
     {
       out.print("<?");
       out.print(nodeName);
       String data = node.getNodeValue();
       if (data != null && data.length() > 0)
       {
         out.print(" ");
         out.print(data);
       }
       out.print("?>");
       break;
     }
     // print comment
     case Node.ruMENT_NODE:
     {
       for (int i = 0; i < prettyIndent; i++)
       {
         out.print(" ");
       }
       out.print("");
       if (prettyprint)
       {
         out.print("\n");
       }
       break;
     }
   }
   if (type == Node.ELEMENT_NODE)
   {
     if (prettyprint)
       prettyIndent--;
     if (hasChildNodes == false)
     {
       out.print("/>");
     }
     else
     {
       if (indentEndMarker)
       {
         for (int i = 0; i < prettyIndent; i++)
         {
           out.print(" ");
         }
       }
       out.print("</");
       out.print(nodeName);
       out.print(">");
     }
     if (prettyIndent > 0)
     {
       out.print("\n");
     }
   }
   out.flush();
 }
 private String getNamespaceURI(String prefix, Element element, Node stopNode)
 {
   Node parent = element.getParentNode();
   String nsURI = element.getAttribute("xmlns:" + prefix);
   if (nsURI.length() == 0 && element != stopNode && parent instanceof Element)
     return getNamespaceURI(prefix, (Element)parent, stopNode);
   return (nsURI.length() > 0 ? nsURI : null);
 }
 private boolean isEndMarkerIndented(Node node)
 {
   if (prettyprint)
   {
     NodeList childNodes = node.getChildNodes();
     int len = childNodes.getLength();
     for (int i = 0; i < len; i++)
     {
       Node children = childNodes.item(i);
       if (children.getNodeType() == Node.ELEMENT_NODE)
       {
         return true;
       }
     }
   }
   return false;
 }
 /** Returns a sorted list of attributes. */
 private Attr[] sortAttributes(NamedNodeMap attrs)
 {
   int len = (attrs != null) ? attrs.getLength() : 0;
   Attr array[] = new Attr[len];
   for (int i = 0; i < len; i++)
   {
     array[i] = (Attr)attrs.item(i);
   }
   for (int i = 0; i < len - 1; i++)
   {
     String name = array[i].getNodeName();
     int index = i;
     for (int j = i + 1; j < len; j++)
     {
       String curName = array[j].getNodeName();
       if (curName.rupareTo(name) < 0)
       {
         name = curName;
         index = j;
       }
     }
     if (index != i)
     {
       Attr temp = array[i];
       array[i] = array[index];
       array[index] = temp;
     }
   }
   return (array);
 }
 /** Normalizes the given string. */
 public static String normalize(String s, boolean canonical)
 {
   StringBuffer str = new StringBuffer();
   int len = (s != null) ? s.length() : 0;
   for (int i = 0; i < len; i++)
   {
     char ch = s.charAt(i);
     switch (ch)
     {
       case "<":
       {
         str.append("<");
         break;
       }
       case ">":
       {
         str.append(">");
         break;
       }
       case "&":
       {
         str.append("&");
         break;
       }
       case """:
       {
         str.append(""");
         break;
       }
       case "\"":
       {
         str.append("'");
         break;
       }
       case "\r":
       case "\n":
       {
         if (canonical)
         {
           str.append("&#");
           str.append(Integer.toString(ch));
           str.append(";");
           break;
         }
         // else, default append char
       }
       default:
       {
         str.append(ch);
       }
     }
   }
   return (str.toString());
 }

}

 </source>
   
  
 
  



Traverse the DOM tree as a list

   <source lang="java">
    

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.traversal.DocumentTraversal; import org.w3c.dom.traversal.NodeFilter; import org.w3c.dom.traversal.NodeIterator; public class Main {

 public static void main(String[] argv) throws Exception {
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   DocumentBuilder loader = factory.newDocumentBuilder();
   Document document = loader.parse("sample.xml");
   DocumentTraversal traversal = (DocumentTraversal) document;
   NodeIterator iterator = traversal.createNodeIterator(document.getDocumentElement(),
       NodeFilter.SHOW_ELEMENT, null, true);
   for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) {
     System.out.println("Element: " + ((Element) n).getTagName());
   }
 }

}



 </source>
   
  
 
  



Traverse the DOM tree using TreeWalker

   <source lang="java">
    

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.traversal.DocumentTraversal; import org.w3c.dom.traversal.NodeFilter; import org.w3c.dom.traversal.TreeWalker; public class Main {

 public static void main(String[] argv) throws Exception {
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   DocumentBuilder loader = factory.newDocumentBuilder();
   Document document = loader.parse("sample.xml");
   DocumentTraversal traversal = (DocumentTraversal) document;
   TreeWalker walker = traversal.createTreeWalker(document.getDocumentElement(),
       NodeFilter.SHOW_ELEMENT, null, true);
   traverseLevel(walker, "");
 }
 private static final void traverseLevel(TreeWalker walker, String indent) {
   Node parend = walker.getCurrentNode();
   System.out.println(indent + "- " + ((Element) parend).getTagName());
   for (Node n = walker.firstChild(); n != null; n = walker.nextSibling()) {
     traverseLevel(walker, indent + "\t");
   }
   walker.setCurrentNode(parend);
 }

}



 </source>
   
  
 
  



Using ranges in DOM tree

   <source lang="java">
    

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.ranges.DocumentRange; import org.w3c.dom.ranges.Range; public class Main {

 public static void main(String[] argv) throws Exception {
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   DocumentBuilder loader = factory.newDocumentBuilder();
   Document document = loader.parse("sample.xml");
   Element order = document.getDocumentElement();
   DocumentRange ranges = (DocumentRange) document;
   Range range = ranges.createRange();
   range.setStartBefore(order.getFirstChild());
   range.setEndAfter(order.getLastChild());
   range.deleteContents();
   range.detach();
 }

}



 </source>