Java/XML/DOM

Материал из Java эксперт
Версия от 07:17, 1 июня 2010; Admin (обсуждение | вклад) (1 версия)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

A utility class which provides methods for working with a W3C DOM

   
/* 
 * This file is part of the Echo Web Application Framework (hereinafter "Echo").
 * Copyright (C) 2002-2009 NextApp, Inc.
 *
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 */

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
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;
/**
 * A utility class which provides methods for working with a W3C DOM.
 */
public class DomUtil {
    public static final Properties OUTPUT_PROPERTIES_INDENT;
    static {
        OUTPUT_PROPERTIES_INDENT = new Properties();
        OUTPUT_PROPERTIES_INDENT.setProperty(OutputKeys.INDENT, "yes");
        OUTPUT_PROPERTIES_INDENT.setProperty("{http://xml.apache.org/xalan}indent-amount", "4");    
    }
    
    /**
     * Entity resolver which throws a SAXException when invoked to avoid external entity injection.
     */
    private static final EntityResolver entityResolver = new EntityResolver() {
    
        /**
         * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String)
         */
        public InputSource resolveEntity(String publicId, String systemId)
        throws SAXException, IOException {
            throw new SAXException("External entities not supported.");
        }
    };
    /**
     * ThreadLocal cache of <code>DocumentBuilder</code> instances.
     */
    private static final ThreadLocal documentBuilders = new ThreadLocal() {
    
        /**
         * @see java.lang.ThreadLocal#initialValue()
         */
        protected Object initialValue() {
            try {
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                factory.setNamespaceAware(true);
                DocumentBuilder builder = factory.newDocumentBuilder();
                builder.setEntityResolver(entityResolver);
                return builder;
            } catch (ParserConfigurationException ex) {
                throw new RuntimeException(ex);
            }
        }
    };
    
    /**
     * ThreadLocal cache of <code>TransformerFactory</code> instances.
     */
    private static final ThreadLocal transformerFactories = new ThreadLocal() {
    
        /**
         * @see java.lang.ThreadLocal#initialValue()
         */
        protected Object initialValue() {
            TransformerFactory factory = TransformerFactory.newInstance();
            return factory;
        }
    };
    
    /**
     * Creates a new document.
     * 
     * @param qualifiedName the qualified name of the document type to be 
     *        created
     * @param publicId the external subset public identifier
     * @param systemId the external subset system identifier
     * @param namespaceUri the namespace URI of the document element to create
     */
    public static Document createDocument(String qualifiedName, String publicId, String systemId, String namespaceUri) {
        DOMImplementation dom = DomUtil.getDocumentBuilder().getDOMImplementation();
        DocumentType docType = dom.createDocumentType(qualifiedName, publicId, systemId);
        Document document = dom.createDocument(namespaceUri, qualifiedName, docType);
        if (namespaceUri != null) {
            document.getDocumentElement().setAttribute("xmlns", namespaceUri);
        }
        return document;
    }
    /**
     * Retrieves a thread-specific <code>DocumentBuilder</code>.
     * As it is a shared resource, the returned object should not be reconfigured in any fashion.
     * 
     * @return the <code>DocumentBuilder</code> serving the current thread.
     */
    public static DocumentBuilder getDocumentBuilder() {
        return (DocumentBuilder) documentBuilders.get();
    }
    
    /**
     * Retrieves a thread-specific <code>TransformerFactory</code>.
     * As it is a shared resource, the returned object should not be reconfigured in any fashion.
     * 
     * @return the <code>TransformerFactory</code> serving the current thread.
     */
    public static TransformerFactory getTransformerFactory() {
        return (TransformerFactory) transformerFactories.get();
    }
    
    /**
     * Determines whether a specific boolean flag is set on an element.
     * 
     * @param element The element to analyze.
     * @param attributeName The name of the boolean "flag" attribute.
     * @return True if the value of the attribute is "true", false if it is
     *         not or if the attribute does not exist.
     */
    public static boolean getBooleanAttribute(Element element, String attributeName) {
        String value = element.getAttribute(attributeName);
        if (value == null) {
            return false;
        } else if (value.equals("true")) {
            return true;
        } else {
            return false;
        }
    }
    /**
     * Retrieves the first immediate child element of the specified element  
     * whose name matches the provided <code>name</code> parameter.
     * 
     * @param parentElement The element to search.
     * @param name The name of the child element.
     * @return The child element, or null if none was found. 
     */
    public static Element getChildElementByTagName(Element parentElement, String name) {
        NodeList nodes = parentElement.getChildNodes();
        int length = nodes.getLength();
        for (int index = 0; index < length; ++index) {
            if (nodes.item(index).getNodeType() == Node.ELEMENT_NODE
                    && name.equals(nodes.item(index).getNodeName())) {
                return (Element) nodes.item(index);
            }
        }
        return null;
    }
    
    /**
     * Retrieves all immediate child elements of the specified element whose
     * names match the provided <code>name</code> parameter.
     * 
     * @param parentElement The element to search.
     * @param name The name of the child element.
     * @return An array of matching child elements.
     */
    public static Element[] getChildElementsByTagName(Element parentElement, String name) {
        List children = new ArrayList();
        NodeList nodes = parentElement.getChildNodes();
        int length = nodes.getLength();
        for (int index = 0; index < length; ++index) {
            if (nodes.item(index).getNodeType() == Node.ELEMENT_NODE
                    && name.equals(nodes.item(index).getNodeName())) {
                children.add(nodes.item(index));
            }
        }
        Element[] childElements = new Element[children.size()];
        return (Element[]) children.toArray(childElements);
    }
    /**
     * Counts the number of immediate child elements of the specified element
     * whose names match the provided <code>name</code> parameter.
     * 
     * @param parentElement The element to analyze.
     * @param name The name of the child element.
     * @return The number of matching child elements.
     */
    public static int getChildElementCountByTagName(Element parentElement, String name) {
        NodeList nodes = parentElement.getChildNodes();
        int length = nodes.getLength();
        int count = 0;
        for (int index = 0; index < length; ++index) {
            if (nodes.item(index).getNodeType() == Node.ELEMENT_NODE
                    && name.equals(nodes.item(index).getNodeName())) {
                ++count;
            }
        }
        return count;
    }
    
    /**
     * Returns the text content of a DOM <code>Element</code>.
     * 
     * @param element The <code>Element</code> to analyze.
     */
    public static String getElementText(Element element) {
        NodeList children = element.getChildNodes();
        int childCount = children.getLength();
        for (int index = 0; index < childCount; ++index) {
            if (children.item(index) instanceof Text) {
                Text text = (Text) children.item(index);
                return text.getData();
            }
        }
        return null;
    }
    
    /**
     * Writes the <code>Document</code> to the specified <code>OutputStream</code>.
     * 
     * @param document the <code>Document</code>
     * @param out the <code>OutputStream</code>
     * @param outputProperties output properties passed to XML transformer
     * @throws SAXException
     */
    public static void save(Document document, OutputStream out, Properties outputProperties) 
    throws SAXException {
        saveImpl(document, new StreamResult(out), outputProperties);
    }
    
    /**
     * Writes the <code>Document</code> to the specified <code>PrintWriter</code>.
     * 
     * @param document the <code>Document</code>
     * @param w the <code>PrintWriter</code>
     * @param outputProperties output properties passed to XML transformer
     * @throws SAXException
     */
    public static void save(Document document, PrintWriter w, Properties outputProperties) 
    throws SAXException {
        saveImpl(document, new StreamResult(w), outputProperties);
    }
    
    /**
     * Work method for public save() methods.
     */
    private static void saveImpl(Document document, StreamResult output, Properties outputProperties) 
    throws SAXException {
        try {
            TransformerFactory tFactory = getTransformerFactory();
            Transformer transformer = tFactory.newTransformer();
            if (outputProperties != null) {
                transformer.setOutputProperties(outputProperties);
            }
            DOMSource source = new DOMSource(document);
            
            transformer.transform(source, output);
        } catch (TransformerException ex) {
            throw new SAXException("Unable to write document to OutputStream.", ex);
        }
    }
    /**
     * Sets the text content of a DOM <code>Element</code>.
     * 
     * @param element The <code>Element</code> to modify.
     * @param value The new text value.
     */
    public static void setElementText(Element element, String value) {
        NodeList children = element.getChildNodes();
        int childCount = children.getLength();
        for (int index = 0; index < childCount; ++index) {
            if (children.item(index) instanceof Text) {
                Text text = (Text) children.item(index);
                text.setData(value);
                return;
            }
        }
        Text text = element.getOwnerDocument().createTextNode(value);
        element.appendChild(text);
    }
    
    /** Non-instantiable class. */
    private DomUtil() { }
}





Check a vendor"s DOM implementation

    
/*-- 
 Copyright (C) 2001 Brett McLaughlin.
 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 disclaimer that follows 
    these conditions in the documentation and/or other materials 
    provided with the distribution.
 3. The name "Java and XML" must not be used to endorse or promote products
    derived from this software without prior written permission.  For
    written permission, please contact brett@newInstance.ru.
 
 In addition, we request (but do not require) that you include in the 
 end-user documentation provided with the redistribution and/or in the 
 software itself an acknowledgement equivalent to the following:
     "This product includes software developed for the
      "Java and XML" book, by Brett McLaughlin (O"Reilly & Associates)."
 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 JDOM AUTHORS OR THE PROJECT
 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.
 */
import org.w3c.dom.DOMImplementation;
/**
 * <b><code>DOMModuleChecker</code></b> checks a vendor"s DOM
 *   implementation, and sees which modules that implementation
 *   makes available.
 */
public class DOMModuleChecker {
    /** Vendor DOMImplementation impl class */
    private String vendorImplementationClass =
        "org.apache.xerces.dom.DOMImplementationImpl";
        
    /** Modules to check */
    private String[] moduleNames =
        {"XML", "Views", "Events", "CSS", "Traversal", "Range", "HTML"};
        
    /**
     * <p>No args constructor uses Apache Xerces DOM
     *   implementation.</p>
     */
    public DOMModuleChecker() {
    }
    
    /**
     * <p>This takes the DOM implementation class to use<p>
     *
     * @param vendorImplementationClass class to use.
     */
    public DOMModuleChecker(String vendorImplementationClass) {
        this.vendorImplementationClass = vendorImplementationClass;
    }
    
    /**
     * <p>This method does the actual work of checking the provided
     *  DOM implementation for the modules it supports.</p>
     *
     * @throws <code>Exception</code> - generic exception handling.
     */
    public void check() throws Exception {
        DOMImplementation impl = 
            (DOMImplementation)Class.forName(vendorImplementationClass)
                                    .newInstance();
        for (int i=0; i<moduleNames.length; i++) {
            if (impl.hasFeature(moduleNames[i], "2.0")) {
                System.out.println("Support for " + moduleNames[i] +
                    " is included in this DOM implementation.");
            } else {
                System.out.println("Support for " + moduleNames[i] +
                    " is not included in this DOM implementation.");                
            }            
        }        
    }    
        
    /**
     * <p>Provide a static entry point.</p>
     */
    public static void main(String[] args) {
        if ((args.length != 0) && (args.length != 1)) {
            System.out.println("Usage: java DOMModuleChecker " +
                "[DOMImplementation impl class to query]");
            System.exit(-1);
        }
        
        try {
            DOMModuleChecker checker = null;
            if (args.length == 1) {
                checker = new DOMModuleChecker(args[1]);
            } else {
                checker = new DOMModuleChecker();
            }
            checker.check();
        } catch (Exception e) {
            e.printStackTrace();
        }               
    }    
}





Convenience methods for working with the DOM API

   
/*
 * Copyright 2002-2007 the original author or authors.
 *
 * 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.util.ArrayList;
import java.util.List;
import org.w3c.dom.CharacterData;
import org.w3c.dom.rument;
import org.w3c.dom.Element;
import org.w3c.dom.EntityReference;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
 * Convenience methods for working with the DOM API,
 * in particular for working with DOM Nodes and DOM Elements.
 *
 * @author Juergen Hoeller
 * @author Rob Harrop
 * @author Costin Leau
 * @since 1.2
 * @see org.w3c.dom.Node
 * @see org.w3c.dom.Element
 */
public abstract class DomUtils {
  /**
   * Retrieve all child elements of the given DOM element that match
   * the given element name. Only look at the direct child level of the
   * given element; do not go into further depth (in contrast to the
   * DOM API"s <code>getElementsByTagName</code> method).
   * @param ele the DOM element to analyze
   * @param childEleName the child element name to look for
   * @return a List of child <code>org.w3c.dom.Element</code> instances
   * @see org.w3c.dom.Element
   * @see org.w3c.dom.Element#getElementsByTagName
   */
  public static List getChildElementsByTagName(Element ele, String childEleName) {
    NodeList nl = ele.getChildNodes();
    List childEles = new ArrayList();
    for (int i = 0; i < nl.getLength(); i++) {
      Node node = nl.item(i);
      if (node instanceof Element && nodeNameEquals(node, childEleName)) {
        childEles.add(node);
      }
    }
    return childEles;
  }
  /**
   * Utility method that returns the first child element
   * identified by its name.
   * @param ele the DOM element to analyze
   * @param childEleName the child element name to look for
   * @return the <code>org.w3c.dom.Element</code> instance,
   * or <code>null</code> if none found
   */
  public static Element getChildElementByTagName(Element ele, String childEleName) {
    NodeList nl = ele.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
      Node node = nl.item(i);
      if (node instanceof Element && nodeNameEquals(node, childEleName)) {
        return (Element) node;
      }
    }
    return null;
  }
  /**
   * Utility method that returns the first child element value
   * identified by its name.
   * @param ele the DOM element to analyze
   * @param childEleName the child element name to look for
   * @return the extracted text value,
   * or <code>null</code> if no child element found
   */
  public static String getChildElementValueByTagName(Element ele, String childEleName) {
    Element child = getChildElementByTagName(ele, childEleName);
    return (child != null ? getTextValue(child) : null);
  }
  /**
   * Namespace-aware equals comparison. Returns <code>true</code> if either
   * {@link Node#getLocalName} or {@link Node#getNodeName} equals <code>desiredName</code>,
   * otherwise returns <code>false</code>.
   */
  public static boolean nodeNameEquals(Node node, String desiredName) {
    return (desiredName.equals(node.getNodeName()) || desiredName.equals(node.getLocalName()));
  }
  /**
   * Extract the text value from the given DOM element, ignoring XML comments.
   * <p>Appends all CharacterData nodes and EntityReference nodes
   * into a single String value, excluding Comment nodes.
   * @see CharacterData
   * @see EntityReference
   * @see Comment
   */
  public static String getTextValue(Element valueEle) {
    StringBuffer value = new StringBuffer();
    NodeList nl = valueEle.getChildNodes();
    for (int i = 0; i < nl.getLength(); i++) {
      Node item = nl.item(i);
      if ((item instanceof CharacterData && !(item instanceof Comment)) || item instanceof EntityReference) {
        value.append(item.getNodeValue());
      }
    }
    return value.toString();
  }
}





Converting an XML Fragment into a DOM Fragment

     
import java.io.File;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
public class Main {
  public static void main(String[] argv) throws Exception {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(true);
    Document doc = factory.newDocumentBuilder().parse(new File("infilename.xml"));
    String fragment = "<fragment>aaa</fragment>";
    factory = DocumentBuilderFactory.newInstance();
    Document d = factory.newDocumentBuilder().parse(new InputSource(new StringReader(fragment)));
    Node node = doc.importNode(d.getDocumentElement(), true);
    DocumentFragment docfrag = doc.createDocumentFragment();
    while (node.hasChildNodes()) {
      docfrag.appendChild(node.removeChild(node.getFirstChild()));
    }
    Element element = doc.getDocumentElement();
    element.appendChild(docfrag);
  }
}





Create an XML document with DOM

     
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
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.DOMImplementation;
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 builder = factory.newDocumentBuilder();
    DOMImplementation impl = builder.getDOMImplementation();
    Document doc = impl.createDocument(null, null, null);
    Element e1 = doc.createElement("api");
    doc.appendChild(e1);
    Element e2 = doc.createElement("java");
    e1.appendChild(e2);
    e2.setAttribute("url", "http://www.domain.ru");
    DOMSource domSource = new DOMSource(doc);
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    transformer.setOutputProperty(OutputKeys.METHOD, "xml");
    transformer.setOutputProperty(OutputKeys.ENCODING, "ISO-8859-1");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    StringWriter sw = new StringWriter();
    StreamResult sr = new StreamResult(sw);
    transformer.transform(domSource, sr);
    System.out.println(sw.toString());
  }
}





Creating XML Document using DOM

     
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
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.Document;
import org.w3c.dom.Element;
public class Main {
  public static void main(String[] args) throws Exception {
    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
    Document newDoc = domBuilder.newDocument();
    Element rootElement = newDoc.createElement("CSV2XML");
    newDoc.appendChild(rootElement);
    BufferedReader csvReader = new BufferedReader(new FileReader("csvFileName.txt"));
    String curLine = csvReader.readLine();
    String[] csvFields = curLine.split(",");
    Element rowElement = newDoc.createElement("row");
    for(String value: csvFields){
      Element curElement = newDoc.createElement(value);
      curElement.appendChild(newDoc.createTextNode(value));
      rowElement.appendChild(curElement);
      rootElement.appendChild(rowElement);
    }
    csvReader.close();
    TransformerFactory tranFactory = TransformerFactory.newInstance();
    Transformer aTransformer = tranFactory.newTransformer();
    Source src = new DOMSource(newDoc);
    Result dest = new StreamResult(new File("xmlFileName"));
    aTransformer.transform(src, dest);
  }
}





DOM Features

    
import org.apache.xerces.dom.DOMImplementationImpl;
import org.w3c.dom.DOMImplementation;
public class DOMFeatures {
  public static void main(String args[]) {
    DOMImplementation domImpl = DOMImplementationImpl.getDOMImplementation();
    String features[] = { "Traversal", "HTML", "CSS", "Range", "XML", "Views", "Events" };
    for (int i = 0; i < features.length; i++) {
      System.out.println("Has " + features[i] + " = " + domImpl.hasFeature(features[i], "2.0"));
    }
  }
}





DOM level 2 Events

    
import org.apache.xerces.parsers.DOMParser;
import org.xml.sax.SAXException;
import org.w3c.dom.*;
import org.apache.xerces.dom.*;
import java.io.IOException;
import org.w3c.dom.events.*;
import org.apache.xerces.dom.events.*;
class MainClass{
  public static void main(String args[]) throws SAXException, IOException {
    new DemoEventsModule();
  }
}
public class DemoEventsModule implements EventListener {

  public DemoEventsModule() throws SAXException, IOException {
    DOMParser parser = new DOMParser();
    parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion",false);
    parser.parse("games.xml");
    Document doc = parser.getDocument();
    Node node = doc.getDocumentElement().getFirstChild();
    Node clone = node.cloneNode(true);
    ((DocumentImpl) doc).addEventListener("DOMNodeRemoved", this, false);
    EventTarget evTarget = (EventTarget) doc;
    evTarget.addEventListener("DOMNodeInserted", this, false);
    doc.getDocumentElement().removeChild(node);
    doc.getDocumentElement().appendChild(clone);
  }
  public void handleEvent(Event ev) {
    if (ev.getType().equals(MutationEventImpl.DOM_NODE_REMOVED)) {
      Node node = (Node) ev.getTarget();
      Node parentNode = node.getParentNode();
      System.out.println("Node " + node.getNodeName()+ " was removed from " + parentNode.getNodeName());
    }
    if (ev.getType().equals(MutationEventImpl.DOM_NODE_INSERTED)) {
      Node node = (Node) ev.getTarget();
      Node parentNode = node.getParentNode();
      System.out.println("Node " + node.getNodeName()+ " was inserted as a child of "+ parentNode.getNodeName());
    }
  }
}
//game.xml
/*
<?xml version="1.0"?>
<games>
<game genre="shooter">XML Invaders</game>
<game genre="rpg">A Node in the XPath</game>
<game genre="action">XPath Racers</game>
</games>

*/





DOM Utils

   
/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000 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 acknowledgment:  
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "SOAP" 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 name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * 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 and was
 * originally based on software copyright (c) 2000, International
 * Business Machines, Inc., http://www.apache.org.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

import org.w3c.dom.*;
/**
 * @author Matthew J. Duftler
 * @author Sanjiva Weerawarana
 */
public class DOMUtils {
  /**
   * The namespaceURI represented by the prefix <code>xmlns</code>.
   */
  private static String NS_URI_XMLNS = "http://www.w3.org/2000/xmlns/";
  /**
   * Returns the value of an attribute of an element. Returns null
   * if the attribute is not found (whereas Element.getAttribute
   * returns "" if an attrib is not found).
   *
   * @param el       Element whose attrib is looked for
   * @param attrName name of attribute to look for 
   * @return the attribute value
   */
  static public String getAttribute (Element el, String attrName) {
    String sRet = null;
    Attr   attr = el.getAttributeNode(attrName);
    if (attr != null) {
      sRet = attr.getValue();
    }
    return sRet;
  }
  /**
   * Returns the value of an attribute of an element. Returns null
   * if the attribute is not found (whereas Element.getAttributeNS
   * returns "" if an attrib is not found).
   *
   * @param el       Element whose attrib is looked for
   * @param namespaceURI namespace URI of attribute to look for 
   * @param localPart local part of attribute to look for 
   * @return the attribute value
   */
  static public String getAttributeNS (Element el,
                                       String namespaceURI,
                                       String localPart) {
    String sRet = null;
    Attr   attr = el.getAttributeNodeNS (namespaceURI, localPart);
    if (attr != null) {
      sRet = attr.getValue ();
    }
    return sRet;
  }
  /**
   * Concat all the text and cdata node children of this elem and return
   * the resulting text.
   *
   * @param parentEl the element whose cdata/text node values are to
   *                 be combined.
   * @return the concatanated string.
   */
  static public String getChildCharacterData (Element parentEl) {
    if (parentEl == null) {
      return null;
    } 
    Node          tempNode = parentEl.getFirstChild();
    StringBuffer  strBuf   = new StringBuffer();
    CharacterData charData;
    while (tempNode != null) {
      switch (tempNode.getNodeType()) {
        case Node.TEXT_NODE :
        case Node.CDATA_SECTION_NODE : charData = (CharacterData)tempNode;
                                       strBuf.append(charData.getData());
                                       break;
      }
      tempNode = tempNode.getNextSibling();
    }
    return strBuf.toString();
  }
  /**
   * Return the first child element of the given element. Null if no
   * children are found.
   *
   * @param elem Element whose child is to be returned
   * @return the first child element.
   */
  public static Element getFirstChildElement (Element elem) {
    for (Node n = elem.getFirstChild (); n != null; n = n.getNextSibling ()) {
      if (n.getNodeType () == Node.ELEMENT_NODE) {
        return (Element) n;
      }
    }
    return null;
  }
  /**
   * Return the next sibling element of the given element. Null if no
   * more sibling elements are found.
   *
   * @param elem Element whose sibling element is to be returned
   * @return the next sibling element.
   */
  public static Element getNextSiblingElement (Element elem) {
    for (Node n = elem.getNextSibling (); n != null; n = n.getNextSibling ()) {
      if (n.getNodeType () == Node.ELEMENT_NODE) {
        return (Element) n;
      }
    }
    return null;
  }
  /**
   * Return the first child element of the given element which has the
   * given attribute with the given value.
   *
   * @param elem      the element whose children are to be searched
   * @param attrName  the attrib that must be present
   * @param attrValue the desired value of the attribute
   *
   * @return the first matching child element.
   */
  public static Element findChildElementWithAttribute (Element elem, 
                   String attrName,
                   String attrValue) {
    for (Node n = elem.getFirstChild (); n != null; n = n.getNextSibling ()) {
      if (n.getNodeType () == Node.ELEMENT_NODE) {
        if (attrValue.equals (DOMUtils.getAttribute ((Element) n, attrName))) {
          return (Element) n;
        }
      }
    }
    return  null;
  }
  /** 
   * Count number of children of a certain type of the given element.
   *
   * @param elem the element whose kids are to be counted
   *
   * @return the number of matching kids.
   */
  public static int countKids (Element elem, short nodeType) {
    int nkids = 0;
    for (Node n = elem.getFirstChild (); n != null; n = n.getNextSibling ()) {
      if (n.getNodeType () == nodeType) {
        nkids++;
      }
    }
    return nkids;
  }
  /**
   * Given a prefix and a node, return the namespace URI that the prefix
   * has been associated with. This method is useful in resolving the
   * namespace URI of attribute values which are being interpreted as
   * QNames. If prefix is null, this method will return the default
   * namespace.
   *
   * @param context the starting node (looks up recursively from here)
   * @param prefix the prefix to find an xmlns:prefix=uri for
   *
   * @return the namespace URI or null if not found
   */
  public static String getNamespaceURIFromPrefix (Node context,
                                                  String prefix) {
    short nodeType = context.getNodeType ();
    Node tempNode = null;
    switch (nodeType)
    {
      case Node.ATTRIBUTE_NODE :
      {
        tempNode = ((Attr) context).getOwnerElement ();
        break;
      }
      case Node.ELEMENT_NODE :
      {
        tempNode = context;
        break;
      }
      default :
      {
        tempNode = context.getParentNode ();
        break;
      }
    }
    while (tempNode != null && tempNode.getNodeType () == Node.ELEMENT_NODE)
    {
      Element tempEl = (Element) tempNode;
      String namespaceURI = (prefix == null)
                            ? getAttribute (tempEl, "xmlns")
                            : getAttributeNS (tempEl, NS_URI_XMLNS, prefix);
      if (namespaceURI != null)
      {
        return namespaceURI;
      }
      else
      {
        tempNode = tempEl.getParentNode ();
      }
    }
    return null;
  }
  public static Element getElementByID(Element el, String id)
  {
    if (el == null)
      return null;
    String thisId = el.getAttribute("id");
    if (id.equals(thisId))
      return el;
    
    NodeList list = el.getChildNodes();
    for (int i = 0; i < list.getLength(); i++) {
      Node node = list.item(i);
      if (node instanceof Element) {
        Element ret = getElementByID((Element)node, id);
        if (ret != null)
          return ret;
      }
    }
    
    return null;
  }
}





Extracting an XML formatted string out of a DOM object

     
import java.io.StringWriter;
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.Document;
public class Main {
  public static void main(String[] argv) throws Exception {
  }
  static String getXMLString(Document xmlDoc) throws Exception {
    StringWriter writer = null;
    DOMSource source = new DOMSource(xmlDoc.getDocumentElement());
    writer = new StringWriter();
    StreamResult result = new StreamResult(writer);
    TransformerFactory tFactory = TransformerFactory.newInstance();
    Transformer transformer = tFactory.newTransformer();
    transformer.transform(source, result);
    StringBuffer strBuf = writer.getBuffer();
    return strBuf.toString();
  }
}





Generating SAX Parsing Events by Traversing a DOM Document

     
import java.io.File;
import java.net.URI;
import javax.xml.parsers.DocumentBuilderFactory;
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.sax.SAXResult;
import org.w3c.dom.Document;
import org.xml.sax.helpers.DefaultHandler;
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"));
    Source source = new DOMSource(doc);
    URI uri = new File("infilename.xml").toURI();
    source.setSystemId(uri.toString());
    DefaultHandler handler = new MyHandler();
    SAXResult result = new SAXResult(handler);
    Transformer xformer = TransformerFactory.newInstance().newTransformer();
    xformer.transform(source, result);
  }
}
class MyHandler extends DefaultHandler {
}





Loading an XML Document using DOM

     
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
public class Main {
  public static void main(String[] args) throws Exception {
    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder domBuilder = domFactory.newDocumentBuilder();
    domBuilder.parse(args[0]);
    System.out.println(""" + args[0] + "" is well-formed.");
  }
}





Make up and write an XML document, using DOM

    
/*
 * Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
 * All rights reserved. Software written by Ian F. Darwin and others.
 * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
 *
 * 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.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
 * AND ANY EXPRESS 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 AUTHOR OR 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.
 * 
 * Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
 * cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
 * pioneering role in inventing and promulgating (and standardizing) the Java 
 * language and environment is gratefully acknowledged.
 * 
 * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
 * inventing predecessor languages C and C++ is also gratefully acknowledged.
 */
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
/** Make up and write an XML document, using DOM
 * UPDATED FOR JAXP.
 * @author Ian Darwin, http://www.darwinsys.ru/
 * @version $Id: DocWriteDOM.java,v 1.6 2004/03/01 03:42:57 ian Exp $
 */
public class DocWriteDOM {
  public static void main(String[] av) throws IOException {
    DocWriteDOM dw = new DocWriteDOM();
    Document doc = dw.makeDoc();
    // Sadly, the write() method is not in the DOM spec, so we
    // have to cast the Document to its implementing class
    // in order to call the Write method.
    //
    // WARNING
    //
    // This code therefore depends upon the particular
    // parser implementation.
    //
    ((org.apache.crimson.tree.XmlDocument)doc).write(System.out);
  }
  /** Generate the XML document */
  protected Document makeDoc() {
    try {
      DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
      DocumentBuilder parser = fact.newDocumentBuilder();
      Document doc = parser.newDocument();
      Node root = doc.createElement("Poem");
      doc.appendChild(root);
      Node stanza = doc.createElement("Stanza");
      root.appendChild(stanza);
      
      Node line = doc.createElement("Line");
      stanza.appendChild(line);
      line.appendChild(doc.createTextNode("Once, upon a midnight dreary"));
      line = doc.createElement("Line");
      stanza.appendChild(line);
      line.appendChild(doc.createTextNode("While I pondered, weak and weary"));
      return doc;
    } catch (Exception ex) {
      System.err.println("+============================+");
      System.err.println("|        XML Error           |");
      System.err.println("+============================+");
      System.err.println(ex.getClass());
      System.err.println(ex.getMessage());
      System.err.println("+============================+");
      return null;
    }
  }
}
// demo xml file
/*
<?xml version="1.0"?>
<people>
<person>
  <name>Ian Darwin</name>
  <email>http://www.darwinsys.ru/</email>
  <country>Canada</country>
</person>
<person>
  <name>Another Darwin</name>
  <email type="intranet">afd@node1</email>
  <country>Canada</country>
</person>
</people>

*/





Parse an XML string: Using DOM and a StringReader.

     
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.CharacterData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
public class Main {
  public static void main(String arg[]) throws Exception{
    String xmlRecords = "<data><employee><name>A</name>"
        + "<title>Manager</title></employee></data>";
    DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    InputSource is = new InputSource();
    is.setCharacterStream(new StringReader(xmlRecords));
    Document doc = db.parse(is);
    NodeList nodes = doc.getElementsByTagName("employee");
    for (int i = 0; i < nodes.getLength(); i++) {
      Element element = (Element) nodes.item(i);
      NodeList name = element.getElementsByTagName("name");
      Element line = (Element) name.item(0);
      System.out.println("Name: " + getCharacterDataFromElement(line));
      NodeList title = element.getElementsByTagName("title");
      line = (Element) title.item(0);
      System.out.println("Title: " + getCharacterDataFromElement(line));
    }
  }
  public static String getCharacterDataFromElement(Element e) {
    Node child = e.getFirstChild();
    if (child instanceof CharacterData) {
      CharacterData cd = (CharacterData) child;
      return cd.getData();
    }
    return "";
  }
}





Parsing a Document Using JAXP

     
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
public class MainClass {
  public static void main(String[] args) throws Exception {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = null;
    db = dbf.newDocumentBuilder();
    Document doc = db.parse(new File("games.xml"));
  }
}





Reading an XML Document and create user-defined object from DOM

     
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.xml.sax.InputSource;
public class ListMoviesXML {
  public static void main(String[] args) throws Exception {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setIgnoringComments(true);
    factory.setIgnoringElementContentWhitespace(true);
    factory.setValidating(true);
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse(new InputSource("y.xml"));
    Element root = doc.getDocumentElement();
    Element movieElement = (Element) root.getFirstChild();
    Movie m;
    while (movieElement != null) {
      m = getMovie(movieElement);
      String msg = Integer.toString(m.year);
      msg += ": " + m.title;
      msg += " (" + m.price + ")";
      System.out.println(msg);
      movieElement = (Element) movieElement.getNextSibling();
    }
  }
  private static Movie getMovie(Element e) {
    String yearString = e.getAttribute("year");
    int year = Integer.parseInt(yearString);
    Element tElement = (Element) e.getFirstChild();
    String title = getTextValue(tElement).trim();
    Element pElement = (Element) tElement.getNextSibling();
    String pString = getTextValue(pElement).trim();
    double price = Double.parseDouble(pString);
    return new Movie(title, year, price);
  }
  private static String getTextValue(Node n) {
    return n.getFirstChild().getNodeValue();
  }
}
class Movie {
  public String title;
  public int year;
  public double price;
  public Movie(String title, int year, double price) {
    this.title = title;
    this.year = year;
    this.price = price;
  }
}





Read XML as DOM

  
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
 *  
 *
 * @author Costin Manolache
 */
public class Main {
  public static class NullResolver implements EntityResolver {
    public InputSource resolveEntity (String publicId,
                                               String systemId)
        throws SAXException, IOException
    {
        return new InputSource(new StringReader(""));
    }
}
  /** Read XML as DOM.
   */
  public static Document readXml(InputStream is)
      throws SAXException, IOException, ParserConfigurationException
  {
      DocumentBuilderFactory dbf =
          DocumentBuilderFactory.newInstance();
      dbf.setValidating(false);
      dbf.setIgnoringComments(false);
      dbf.setIgnoringElementContentWhitespace(true);
      //dbf.setCoalescing(true);
      //dbf.setExpandEntityReferences(true);
      DocumentBuilder db = null;
      db = dbf.newDocumentBuilder();
      db.setEntityResolver( new NullResolver() );
      // db.setErrorHandler( new MyErrorHandler());
      Document doc = db.parse(is);
      return doc;
  }
}





Searching through a document

    
/*-- 
 Copyright (C) 2001 Brett McLaughlin.
 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 disclaimer that follows 
    these conditions in the documentation and/or other materials 
    provided with the distribution.
 3. The name "Java and XML" must not be used to endorse or promote products
    derived from this software without prior written permission.  For
    written permission, please contact brett@newInstance.ru.
 
 In addition, we request (but do not require) that you include in the 
 end-user documentation provided with the redistribution and/or in the 
 software itself an acknowledgement equivalent to the following:
     "This product includes software developed for the
      "Java and XML" book, by Brett McLaughlin (O"Reilly & Associates)."
 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 JDOM AUTHORS OR THE PROJECT
 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.
 */
import java.io.File;
// DOM imports
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
// Vendor parser
import org.apache.xerces.parsers.DOMParser;
/**
 * <b><code>ItemSearcher</code></b> shows how the DOM Level 2 Traversal
 *   module can be used for searching through a document.
 */
public class ItemSearcher {
    /** The default namespace for the document to search through */
    private String docNS = "http://www.oreilly.ru/javaxml2";
    /**
     * <p>This method takes a file, and searches it for specific
     *   pieces of data using DOM traversal.</p>
     *
     * @param filename name of XML file to search through.
     * @throws <code>Exception</code> - generic problem handling.
     */
    public void search(String filename) throws Exception {
        // Parse into a DOM tree
        File file = new File(filename);
        DOMParser parser = new DOMParser();
        parser.parse(file.toURL().toString());
        Document doc = parser.getDocument();
        // Get node to start iterating with
        Element root = doc.getDocumentElement();
        NodeList descriptionElements = 
            root.getElementsByTagNameNS(docNS, "description");
        Element description = (Element)descriptionElements.item(0);
        // Get a NodeIterator
        NodeIterator i = ((DocumentTraversal)doc)
            .createNodeIterator(description, NodeFilter.SHOW_ALL, 
                new FormattingNodeFilter(), true);
        Node n;
        while ((n = i.nextNode()) != null) {
            System.out.println("Search phrase found: "" + n.getNodeValue() + """);
        }
    }
    /**
     * <p>Provide a static entry point.</p>
     */
    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("No item files to search through specified.");
            return;
        }
        try {
            ItemSearcher searcher = new ItemSearcher();
            for (int i=0; i<args.length; i++) {
                System.out.println("Processing file: " + args[i]);
                searcher.search(args[i]);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class FormattingNodeFilter implements NodeFilter {
    public short acceptNode(Node n) {
        if (n.getNodeType() == Node.TEXT_NODE) {
            Node parent = n.getParentNode();
            if ((parent.getNodeName().equalsIgnoreCase("b")) ||
                (parent.getNodeName().equalsIgnoreCase("i"))) {
                return FILTER_ACCEPT;
            }
        }
        // If we got here, not interested
        return FILTER_SKIP;
    }
}





Using DOM for Syntax Checking

    
//Example XML document
/*
An XML Document Containing a Simple Contact List
Start example
<?xml version="1.0" standalone="yes"?>
<folks>
   <person>
       <phone>306 555-9999</phone>
       <email>joe@webserver.net</email>
       <name>Wang, Joe</name>
   </person>
   <person>
       <phone>704 555-0000</phone>
       <name>Pet, Rob</name>
       <email>rob@server.ru</email>
   </person>
</folks>
*/
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class DOMCheck {
   static public void main(String[] arg) {
       String filename = null;
       boolean validate = false;
       if(arg.length == 1) {
           filename = arg[0];
       } else if(arg.length == 2) {
           if(!arg[0].equals("-v"))
               usage();
           validate = true;
           filename = arg[1];
       } else {
           usage();
       }
       // Create a new factory to create parsers that will
       // be aware of namespaces and will validate or
       // not according to the flag setting.
       DocumentBuilderFactory dbf = 
DocumentBuilderFactory.newInstance();
       dbf.setValidating(validate);
       dbf.setNamespaceAware(true);
       // Use the factory to create a parser (builder) and use
       // it to parse the document.
       try {
           DocumentBuilder builder = dbf.newDocumentBuilder();
           builder.setErrorHandler(new MyErrorHandler());
           InputSource is = new InputSource(filename);
           Document doc = builder.parse(is);
       } catch (SAXException e) {
           System.exit(1);
       } catch (ParserConfigurationException e) {
           System.err.println(e);
           System.exit(1);
       } catch (IOException e) {
           System.err.println(e);
           System.exit(1);
       }
   }
   private static void usage() {
       System.err.println("Usage: DOMCheck [-v] <filename>");
       System.exit(1);
   }
}
class MyErrorHandler implements ErrorHandler {
  public void warning(SAXParseException e) throws SAXException {
    show("Warning", e);
    throw (e);
  }
  public void error(SAXParseException e) throws SAXException {
    show("Error", e);
    throw (e);
  }
  public void fatalError(SAXParseException e) throws SAXException {
    show("Fatal Error", e);
    throw (e);
  }
  private void show(String type, SAXParseException e) {
    System.out.println(type + ": " + e.getMessage());
    System.out.println("Line " + e.getLineNumber() + " Column "
        + e.getColumnNumber());
    System.out.println("System ID: " + e.getSystemId());
  }
}





Using the DOM Parser to Build a Document Tree

    
//Example XML document
/*
An XML Document Containing a Simple Contact List
<?xml version="1.0" standalone="yes"?>
<folks>
   <person>
       <phone>306 555-9999</phone>
       <email>joe@webserver.net</email>
       <name>Wang, Joe</name>
   </person>
   <person>
       <phone>704 555-0000</phone>
       <name>Pet, Rob</name>
       <email>rob@server.ru</email>
   </person>
</folks>
*/
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class DOMDump {
  static public void main(String[] arg) {
    String filename = null;
    boolean validate = false;
    if (arg.length == 1) {
      filename = arg[0];
    } else if (arg.length == 2) {
      if (!arg[0].equals("-v"))
        usage();
      validate = true;
      filename = arg[1];
    } else {
      usage();
    }
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setValidating(validate);
    dbf.setNamespaceAware(true);
    dbf.setIgnoringElementContentWhitespace(true);
    // Parse the input to produce a parse tree with its root
    // in the form of a Document object
    Document doc = null;
    try {
      DocumentBuilder builder = dbf.newDocumentBuilder();
      builder.setErrorHandler(new MyErrorHandler());
      InputSource is = new InputSource(filename);
      doc = builder.parse(is);
    } catch (SAXException e) {
      System.exit(1);
    } catch (ParserConfigurationException e) {
      System.err.println(e);
      System.exit(1);
    } catch (IOException e) {
      System.err.println(e);
      System.exit(1);
    }
    // Use a TreeDumper to list the tree
    TreeDumper td = new TreeDumper();
    td.dump(doc);
  }
  private static void usage() {
    System.err.println("Usage: DOMCheck [-v] <filename>");
    System.exit(1);
  }
}
class TreeDumper {
    public void dump(Document doc) {
        dumpLoop((Node)doc,"");
    }
    private void dumpLoop(Node node,String indent) {
        switch(node.getNodeType()) {
        case Node.CDATA_SECTION_NODE:
            System.out.println(indent + "CDATA_SECTION_NODE");
            break;
        case Node.ruMENT_NODE:
            System.out.println(indent + "COMMENT_NODE");
            break;
        case Node.DOCUMENT_FRAGMENT_NODE:
            System.out.println(indent + "DOCUMENT_FRAGMENT_NODE");
            break;
        case Node.DOCUMENT_NODE:
            System.out.println(indent + "DOCUMENT_NODE");
            break;
        case Node.DOCUMENT_TYPE_NODE:
            System.out.println(indent + "DOCUMENT_TYPE_NODE");
            break;
        case Node.ELEMENT_NODE:
            System.out.println(indent + "ELEMENT_NODE");
            break;
        case Node.ENTITY_NODE:
            System.out.println(indent + "ENTITY_NODE");
            break;
        case Node.ENTITY_REFERENCE_NODE:
            System.out.println(indent + "ENTITY_REFERENCE_NODE");
            break;
        case Node.NOTATION_NODE:
            System.out.println(indent + "NOTATION_NODE");
            break;
        case Node.PROCESSING_INSTRUCTION_NODE:
            System.out.println(indent + "PROCESSING_INSTRUCTION_NODE");
            break;
        case Node.TEXT_NODE:
            System.out.println(indent + "TEXT_NODE");
            break;
        default:
            System.out.println(indent + "Unknown node");
            break;
        }
        NodeList list = node.getChildNodes();
        for(int i=0; i<list.getLength(); i++)
            dumpLoop(list.item(i),indent + "   ");
    }
}
class MyErrorHandler implements ErrorHandler {
  public void warning(SAXParseException e) throws SAXException {
    show("Warning", e);
    throw (e);
  }
  public void error(SAXParseException e) throws SAXException {
    show("Error", e);
    throw (e);
  }
  public void fatalError(SAXParseException e) throws SAXException {
    show("Fatal Error", e);
    throw (e);
  }
  private void show(String type, SAXParseException e) {
    System.out.println(type + ": " + e.getMessage());
    System.out.println("Line " + e.getLineNumber() + " Column "
        + e.getColumnNumber());
    System.out.println("System ID: " + e.getSystemId());
  }
}





Utilities to read DOM

   
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
 * Few simple utils to read DOM
 * 
 * @author Costin Manolache
 */
public class DomUtil {
  // -------------------- DOM utils --------------------
  /**
   * 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 = DomUtil.getChild(n, Node.TEXT_NODE);
    if (n1 == null)
      return null;
    String s1 = n1.getNodeValue();
    return s1.trim();
  }
  /**
   * Get the first element child.
   * 
   * @param parent
   *          lookup direct childs
   * @param name
   *          name of the element. If null return the first element.
   */
  public static Node getChild(Node parent, String name) {
    if (parent == null)
      return null;
    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 (node.getNodeType() != Node.ELEMENT_NODE)
        continue;
      if (name != null && name.equals(node.getNodeName())) {
        return node;
      }
      if (name == null) {
        return node;
      }
    }
    return null;
  }
  public static String getAttribute(Node element, String attName) {
    NamedNodeMap attrs = element.getAttributes();
    if (attrs == null)
      return null;
    Node attN = attrs.getNamedItem(attName);
    if (attN == null)
      return null;
    return attN.getNodeValue();
  }
  public static void setAttribute(Node node, String attName, String val) {
    NamedNodeMap attributes = node.getAttributes();
    Node attNode = node.getOwnerDocument().createAttribute(attName);
    attNode.setNodeValue(val);
    attributes.setNamedItem(attNode);
  }
  public static void removeAttribute(Node node, String attName) {
    NamedNodeMap attributes = node.getAttributes();
    attributes.removeNamedItem(attName);
  }
  /**
   * Set or replace the text value
   */
  public static void setText(Node node, String val) {
    Node chld = DomUtil.getChild(node, Node.TEXT_NODE);
    if (chld == null) {
      Node textN = node.getOwnerDocument().createTextNode(val);
      node.appendChild(textN);
      return;
    }
    // change the value
    chld.setNodeValue(val);
  }
  /**
   * Find the first direct child with a given attribute.
   * 
   * @param parent
   * @param elemName
   *          name of the element, or null for any
   * @param attName
   *          attribute we"re looking for
   * @param attVal
   *          attribute value or null if we just want any
   */
  public static Node findChildWithAtt(Node parent, String elemName, String attName, String attVal) {
    Node child = DomUtil.getChild(parent, Node.ELEMENT_NODE);
    if (attVal == null) {
      while (child != null && (elemName == null || elemName.equals(child.getNodeName()))
          && DomUtil.getAttribute(child, attName) != null) {
        child = getNext(child, elemName, Node.ELEMENT_NODE);
      }
    } else {
      while (child != null && (elemName == null || elemName.equals(child.getNodeName()))
          && !attVal.equals(DomUtil.getAttribute(child, attName))) {
        child = getNext(child, elemName, Node.ELEMENT_NODE);
      }
    }
    return child;
  }
  /**
   * 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 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;
  }
  /**
   * Get the next sibling with the same name and type
   */
  public static Node getNext(Node current) {
    String name = current.getNodeName();
    int type = current.getNodeType();
    return getNext(current, name, type);
  }
  /**
   * Return the next sibling with a given name and type
   */
  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;
  }
  public static class NullResolver implements EntityResolver {
    public InputSource resolveEntity(String publicId, String systemId) throws SAXException,
        IOException {
      return new InputSource(new StringReader(""));
    }
  }
  /**
   * Read XML as DOM.
   */
  public static Document readXml(InputStream is) throws SAXException, IOException,
      ParserConfigurationException {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setValidating(false);
    dbf.setIgnoringComments(false);
    dbf.setIgnoringElementContentWhitespace(true);
    // dbf.setCoalescing(true);
    // dbf.setExpandEntityReferences(true);
    DocumentBuilder db = null;
    db = dbf.newDocumentBuilder();
    db.setEntityResolver(new NullResolver());
    // db.setErrorHandler( new MyErrorHandler());
    Document doc = db.parse(is);
    return doc;
  }
  public static void writeXml(Node n, OutputStream os) throws TransformerException {
    TransformerFactory tf = TransformerFactory.newInstance();
    // identity
    Transformer t = tf.newTransformer();
    t.setOutputProperty(OutputKeys.INDENT, "yes");
    t.transform(new DOMSource(n), new StreamResult(os));
  }
}





Utility method for parsing the XML with DOM

 
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common
 * Development and Distribution License("CDDL") (collectively, the
 * "License"). You may not use this file except in compliance with the
 * License. You can obtain a copy of the License at
 * http://www.netbeans.org/cddl-gplv2.html
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 * specific language governing permissions and limitations under the
 * License.  When distributing the software, include this License Header
 * Notice in each file and include the License file at
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the GPL Version 2 section of the License file that
 * accompanied this code. If applicable, add the following below the
 * License Header, with the fields enclosed by brackets [] replaced by
 * your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * Contributor(s):
 *
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 * Microsystems, Inc. All Rights Reserved.
 *
 * If you wish your version of this file to be governed by only the CDDL
 * or only the GPL Version 2, indicate your decision by adding
 * "[Contributor] elects to include this software in this distribution
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 * single choice of license, a recipient has the option to distribute
 * your version of this file under either the CDDL, the GPL Version 2 or
 * to extend the choice of license to its licensees as provided above.
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 * Version 2 license, then the option applies only if the new code is
 * made subject to such option by the copyright holder.
 */
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
 * Utility class collecting library methods related to XML processing. Stolen
 * from nbbuild/antsrc and openide/.../xml.
 * 
 * @author Petr Kuzel, Jesse Glick
 */
public final class XMLUtil {
  public static Document parse(InputSource input, boolean validate, boolean namespaceAware,
      ErrorHandler errorHandler, EntityResolver entityResolver) throws IOException, SAXException {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setValidating(validate);
    factory.setNamespaceAware(namespaceAware);
    DocumentBuilder builder = null;
    try {
      builder = factory.newDocumentBuilder();
    } catch (ParserConfigurationException ex) {
      throw new SAXException(ex);
    }
    if (errorHandler != null) {
      builder.setErrorHandler(errorHandler);
    }
    if (entityResolver != null) {
      builder.setEntityResolver(entityResolver);
    }
    assert input != null : "InputSource cannot be null";
    return builder.parse(input);
  }
}





Visiting All the Nodes in a DOM Document

     
import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
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 doc = factory.newDocumentBuilder().parse(new File("filename"));
    visit(doc, 0);
  }
  public static void visit(Node node, int level) {
    NodeList list = node.getChildNodes();
    for (int i = 0; i < list.getLength(); i++) {
      Node childNode = list.item(i);
      visit(childNode, level + 1);
    }
  }
}





W3C DOM utility methods

   
/*
  Milyn - Copyright (C) 2006
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License (version 2.1) as published by the Free Software 
  Foundation.
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
    
  See the GNU Lesser General Public License for more details:    
  http://www.gnu.org/licenses/lgpl.txt
*/

import java.util.List;
import java.util.Vector;
import org.w3c.dom.Attr;
import org.w3c.dom.rument;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
/**
 * W3C DOM utility methods.
 * @author tfennelly
 */
public abstract class DomUtils {
  /**
   * Copy child node references from source to target.
   * @param source Source Node.
   * @param target Target Node.
   */
  public static void copyChildNodes(Node source, Node target) {
    List nodeList = DomUtils.copyNodeList(source.getChildNodes());
    int childCount = nodeList.size();
    
    for(int i = 0; i < childCount; i++) {
      target.appendChild((Node)nodeList.get(i));
    }
  }
  
  /**
   * Replace one node with another node.
   * @param newNode New node - added in same location as oldNode.
   * @param oldNode Old node - removed.
   */
  public static void replaceNode(Node newNode, Node oldNode) {

    Node parentNode = oldNode.getParentNode();
    
    if(parentNode == null) {
      System.out.println("Cannot replace node [" + oldNode + "] with [" + newNode + "]. [" + oldNode + "] has no parent.");
    } else {
      parentNode.replaceChild(newNode, oldNode);
    }
  }
  
  /**
   * Replace one node with a list of nodes.
   * <p/>
   * Clones the NodeList elements.
   * @param newNodes New nodes - added in same location as oldNode.
   * @param oldNode Old node - removed.
   */
  public static void replaceNode(NodeList newNodes, Node oldNode) {
    replaceNode(newNodes, oldNode, true);
  }
  
  /**
   * Replace one node with a list of nodes.
   * @param newNodes New nodes - added in same location as oldNode.
   * @param oldNode Old node - removed.
   * @param clone Clone Nodelist Nodes.
   */
  public static void replaceNode(NodeList newNodes, Node oldNode, boolean clone) {

    Node parentNode = oldNode.getParentNode();
        if(parentNode == null) {
          System.out.println("Cannot replace [" + oldNode + "] with a NodeList. [" + oldNode + "] has no parent.");
      return;
    }
    
    int nodeCount = newNodes.getLength();
    List nodeList = DomUtils.copyNodeList(newNodes);
        
        if(nodeCount == 0) {
            if(!(parentNode instanceof Document)) {
              parentNode.removeChild(oldNode);
            }
            return;
        }
        
        if(parentNode instanceof Document) {
      List elements = DomUtils.getElements(newNodes, "*", null);
      if(!elements.isEmpty()) {
        System.out.println("Request to replace the Document root node with a 1+ in length NodeList.  Replacing root node with the first element node from the NodeList.");
              parentNode.removeChild(oldNode);
              parentNode.appendChild((Node)elements.get(0));
      } else {
        System.out.println("Cannot replace document root element with a NodeList that doesn"t contain an element node.");
      }
        } else {
        for(int i = 0; i < nodeCount; i++) {
          if(clone) {
            parentNode.insertBefore(((Node)nodeList.get(i)).cloneNode(true), oldNode);
          } else {
            parentNode.insertBefore((Node)nodeList.get(i), oldNode);
          }
        }
        parentNode.removeChild(oldNode);
        }
  }
    /**
     * Insert the supplied node before the supplied reference node (refNode).
     * @param newNode Node to be inserted.
     * @param refNode Reference node before which the supplied nodes should
     * be inserted.
     */
    public static void insertBefore(Node newNode, Node refNode) {

      Node parentNode = refNode.getParentNode();
      
      if(parentNode == null) {
        System.out.println("Cannot insert [" + newNode + "] before [" + refNode + "]. [" + refNode + "] has no parent.");
      return;
    }
        
        if(parentNode instanceof Document && newNode.getNodeType() == Node.ELEMENT_NODE) {
          System.out.println("Request to insert an element before the Document root node.  This is not allowed.  Replacing the Document root with the new Node.");
            parentNode.removeChild(refNode);
            parentNode.appendChild(newNode);
        } else {
            parentNode.insertBefore(newNode, refNode);
        }
    }
  /**
   * Insert the supplied nodes before the supplied reference node (refNode).
   * @param newNodes Nodes to be inserted.
   * @param refNode Reference node before which the supplied nodes should
   * be inserted.
   */
  public static void insertBefore(NodeList newNodes, Node refNode) {

    
    Node parentNode = refNode.getParentNode();
    
    if(parentNode == null) {
      System.out.println("Cannot insert a NodeList before [" + refNode + "]. [" + refNode + "] has no parent.");
      return;
    }
    
    int nodeCount = newNodes.getLength();
    List nodeList = DomUtils.copyNodeList(newNodes);
    
        if(nodeCount == 0) {
            return;
        }
        
        if(parentNode instanceof Document) {
      List elements = DomUtils.getElements(newNodes, "*", null);
      if(!elements.isEmpty()) {
        System.out.println("Request to insert a NodeList before the Document root node.  Will replace the root element with the 1st element node from the NodeList.");
              parentNode.removeChild(refNode);
              parentNode.appendChild((Node)elements.get(0));
      } else {
        System.out.println("Cannot insert beforen the document root element from a NodeList that doesn"t contain an element node.");
      }
          
        for(int i = 0; i < nodeCount; i++) {
          Node node = (Node)nodeList.get(i);
          if(node.getNodeType() != Node.ELEMENT_NODE) {
            System.out.println("****" + node);
            parentNode.insertBefore(node, refNode);
          }
        }
        } else {
        for(int i = 0; i < nodeCount; i++) {
          parentNode.insertBefore((Node)nodeList.get(i), refNode);
        }
        }
  }
  /**
   * Rename element.
   * @param element The element to be renamed.
   * @param replacementElement The tag name of the replacement element.
   * @param keepChildContent <code>true</code> if the target element"s child content
   * is to be copied to the replacement element, false if not. Default <code>true</code>.
   * @param keepAttributes <code>true</code> if the target element"s attributes
   * are to be copied to the replacement element, false if not. Default <code>true</code>.
   * @return The renamed element.
   */
  public static Element renameElement(Element element, String replacementElement, boolean keepChildContent, boolean keepAttributes) {

    
    Element replacement = element.getOwnerDocument().createElement(replacementElement);
    if(keepChildContent) {
      DomUtils.copyChildNodes(element, replacement);
    }
    if(keepAttributes) { 
      NamedNodeMap attributes = element.getAttributes();
      int attributeCount = attributes.getLength();
      
      for(int i = 0; i < attributeCount; i++) {
        Attr attribute = (Attr)attributes.item(i);
        replacement.setAttribute(attribute.getName(), attribute.getValue());
      }
    }
    DomUtils.replaceNode(replacement, element);
    
    return replacement;
  }
  /**
   * Remove the supplied element from its containing document.
   * <p/>
   * Tries to manage scenarios where a request is made to remove the root element.
   * Cannot remove the root element in any of the following situations:
   * <ul>
   *  <li>"keepChildren" parameter is false.</li>
   *  <li>root element is empty of {@link Node#ELEMENT_NODE} nodes.</li>
   * </ul>
   * @param element Element to be removed.
   * @param keepChildren Keep child content.
   */
  public static void removeElement(Element element, boolean keepChildren) {

    Node parent = element.getParentNode();
    if(parent == null) {
      System.out.println("Cannot remove element [" + element + "]. [" + element + "] has no parent.");
      return;
    }
    
    NodeList children = element.getChildNodes();
    
    if (parent instanceof Document) {
      List childElements = null;
      
      if(!keepChildren) {
        System.out.println("Cannot remove document root element [" + DomUtils.getName(element) + "] without keeping child content.");
      } else {
        if(children != null && children.getLength() > 0) {
          childElements = DomUtils.getElements(element, "*", null);
        }
        
        if(childElements != null && !childElements.isEmpty()) {
          parent.removeChild(element);
          parent.appendChild((Element)childElements.get(0));
        } else {
          System.out.println("Cannot remove empty document root element [" + DomUtils.getName(element) + "].");
        }
      }
    } else {
      if(keepChildren && children != null) {
        DomUtils.insertBefore(children, element);
      }
      parent.removeChild(element);        
    }
  }
  
  /**
   * Remove all child nodes from the supplied node.
   * @param node to be "cleared".
   */
  public static void removeChildren(Node node) {

    NodeList children = node.getChildNodes();
    int nodeCount = children.getLength();
    
    for(int i = 0; i < nodeCount; i++) {
      node.removeChild(children.item(0));
    }
  }
  /**
   * Copy the nodes of a NodeList into the supplied list.
   * <p/>
   * This is not a clone.  It"s just a copy of the node references.
   * <p/>
   * Allows iteration over the Nodelist using the copy in the knowledge that
   * the list will remain the same length.  Using the NodeList can result in problems
   * because elements can get removed from the list while we"re iterating over it.
   * @param nodeList Nodelist to copy.
   * @return List copy.
   */
  public static List copyNodeList(NodeList nodeList) {
    Vector copy = new Vector();
    
    if(nodeList != null) {
      int nodeCount = nodeList.getLength();
    
      for(int i = 0; i < nodeCount; i++) {
        copy.add(nodeList.item(i));
      }
    }
    
    return copy;
  }
  
  /**
   * Append the nodes from the supplied list to the supplied node. 
   * @param node Node to be appended to.
   * @param nodes List of nodes to append.
   */
  public static void appendList(Node node, List nodes) {

    int nodeCount = nodes.size();
  
    for(int i = 0; i < nodeCount; i++) {
      node.appendChild((Node)nodes.get(i));
    }
  }
  
  /**
   * Get a boolean attribute from the supplied element.
   * @param element The element.
   * @param attribName The attribute name.
   * @return True if the attribute value is "true" (case insensitive), otherwise false.
   */
  public static boolean getBooleanAttrib(Element element, String attribName) {

    String attribVal = element.getAttribute(attribName);
    
    return (attribVal != null?attribVal.equalsIgnoreCase("true"):false);
  }
  
  /**
   * Get a boolean attribute from the supplied element.
   * @param element The element.
   * @param namespaceURI Namespace URI of the required attribute.
   * @param attribName The attribute name.
   * @return True if the attribute value is "true" (case insensitive), otherwise false.
   */
  public static boolean getBooleanAttrib(Element element, String attribName, String namespaceURI) {


    String attribVal = element.getAttributeNS(namespaceURI, attribName);
    
    return (attribVal != null?attribVal.equalsIgnoreCase("true"):false);
  }
  
  /**
   * Get the parent element of the supplied element having the
   * specified tag name.
   * @param child Child element. 
   * @param parentLocalName Parent element local name.
   * @return The first parent element of "child" having the tagname "parentName",
   * or null if no such parent element exists.
   */
  public static Element getParentElement(Element child, String parentLocalName) {
    return getParentElement(child, parentLocalName, null);
  }
  
  /**
   * Get the parent element of the supplied element having the
   * specified tag name.
   * @param child Child element. 
   * @param parentLocalName Parent element local name.
   * @param namespaceURI Namespace URI of the required parent element,
   * or null if a non-namespaced get is to be performed.
   * @return The first parent element of "child" having the tagname "parentName",
   * or null if no such parent element exists.
   */
  public static Element getParentElement(Element child, String parentLocalName, String namespaceURI) {

    Node parentNode = child.getParentNode();
    
    while(parentNode != null && parentNode.getNodeType() == Node.ELEMENT_NODE) {
      Element parentElement = (Element)parentNode;
      if(getName(parentElement).equalsIgnoreCase(parentLocalName)) {
        if(namespaceURI == null) {
          return parentElement;
        } else if(parentElement.getNamespaceURI().equals(namespaceURI)) {
          return parentElement;
        }
      }
      parentNode = parentNode.getParentNode();
    }
    
    return null;
  }
  /**
   * Get the name from the supplied element.
   * <p/>
   * Returns the {@link Node#getLocalName() localName} of the element
   * if set (namespaced element), otherwise the 
   * element"s {@link Element#getTagName() tagName} is returned.
   * @param element The element.
   * @return The element name.
   */
  public static String getName(Element element) {
    String name = element.getLocalName();
    
    if(name != null) {
      return name;
    } else {
      return element.getTagName();
    }
  }
  
  /**
   * Get attribute value, returning <code>null</code> if unset.
   * <p/>
   * Some DOM implementations return an empty string for an unset
   * attribute.
   * @param element The DOM element.
   * @param attributeName The attribute to get.
   * @return The attribute value, or <code>null</code> if unset.
   */
  public static String getAttributeValue(Element element, String attributeName) {
    return getAttributeValue(element, attributeName, null);
  }
  
  /**
   * Get attribute value, returning <code>null</code> if unset.
   * <p/>
   * Some DOM implementations return an empty string for an unset
   * attribute.
   * @param element The DOM element.
   * @param attributeName The attribute to get.
   * @param namespaceURI Namespace URI of the required attribute, or null
   * to perform a non-namespaced get.
   * @return The attribute value, or <code>null</code> if unset.
   */
  public static String getAttributeValue(Element element, String attributeName, String namespaceURI) {

    String attributeValue;
    
    if(namespaceURI == null) {
      attributeValue = element.getAttribute(attributeName);
    } else {
      attributeValue = element.getAttributeNS(namespaceURI, attributeName);
    }
    
    if(attributeValue.length() == 0 && !element.hasAttribute(attributeName)) {
      return null;
    }
    
    return attributeValue;
  }
  public static Node getPreviousSibling(Node node, short nodeType) {
    Node parent = node.getParentNode();
        if(parent == null) {
          System.out.println("Cannot get node [" + node + "] previous sibling. [" + node + "] has no parent.");
      return null;
    }
    
    NodeList siblings = parent.getChildNodes();
    int siblingCount = siblings.getLength();
    int nodeIndex = 0;
    
    // Locate the node
    for(int i = 0; i < siblingCount; i++) {
      Node sibling = siblings.item(i);
      
      if(sibling == node) {
        nodeIndex = i;
        break;
      }
    }
    
    if(nodeIndex == 0) {
      return null;
    }
    // Wind back to sibling
    for(int i = nodeIndex - 1; i >= 0; i--) {
      Node sibling = siblings.item(i);
      
      if(sibling.getNodeType() == nodeType) {
        return sibling;
      }
    }
    
    return null;
  }
  
  /**
   * Count the DOM nodes of the supplied type (nodeType) before the supplied
   * node, not including the node itself.
   * <p/>
   * Counts the sibling nodes.
   * @param node Node whose siblings are to be counted.
   * @param nodeType The DOM {@link Node} type of the siblings to be counted. 
   * @return The number of siblings of the supplied type before the supplied node.
   */
  public static int countNodesBefore(Node node, short nodeType) {
    Node parent = node.getParentNode();
        if(parent == null) {
          System.out.println("Cannot count nodes before [" + node + "]. [" + node + "] has no parent.");
      return 0;
    }
        NodeList siblings = parent.getChildNodes();
    int count = 0;
    int siblingCount = siblings.getLength();
    
    for(int i = 0; i < siblingCount; i++) {
      Node sibling = siblings.item(i);
      
      if(sibling == node) {
        break;
      }
      if(sibling.getNodeType() == nodeType) {
        count++;
      }     
    }
    
    return count;
  }
  /**
   * Count the DOM nodes of the supplied type (nodeType) between the supplied
   * sibling nodes, not including the nodes themselves.
   * <p/>
   * Counts the sibling nodes.
   * @param node1 First sibling node.
   * @param node2 Second sibling node.
   * @param nodeType The DOM {@link Node} type of the siblings to be counted. 
   * @return The number of siblings of the supplied type between the supplied
   * sibling nodes.
   * @throws UnsupportedOperationException if the supplied {@link Node Nodes}
   * don"t have the same parent node i.e. are not sibling nodes.
   */
  public static int countNodesBetween(Node node1, Node node2, short nodeType) {
    Node parent1 = node1.getParentNode();
        if(parent1 == null) {
          System.out.println("Cannot count nodes between [" + node1 + "] and [" + node2 + "]. [" + node1 + "] has no parent.");
      return 0;
    }
    
    Node parent2 = node2.getParentNode();
        if(parent2 == null) {
          System.out.println("Cannot count nodes between [" + node1 + "] and [" + node2 + "]. [" + node2 + "] has no parent.");
      return 0;
    }
    
    if(parent1 != parent2) {
      System.out.println("Cannot count nodes between [" + node1 + "] and [" + node2 + "]. These nodes do not share the same sparent.");
      return 0;
    }
    
    int countBeforeNode1 = countNodesBefore(node1, nodeType);
    int countBeforeNode2 = countNodesBefore(node2, nodeType);
    int count = countBeforeNode2 - countBeforeNode1;
    
    if(node1.getNodeType() == nodeType) {
      count--;
    }
    
    return count;
  }
  /**
   * Count the DOM nodes before the supplied node, not including the node itself.
   * <p/>
   * Counts the sibling nodes.
   * @param node Node whose siblings are to be counted.
   * @return The number of siblings before the supplied node.
   */
  public static int countNodesBefore(Node node) {
    Node parent = node.getParentNode();
        if(parent == null) {
          System.out.println("Cannot count nodes before [" + node + "]. [" + node + "] has no parent.");
      return 0;
    }
    NodeList siblings = parent.getChildNodes();
    int count = 0;
    int siblingCount = siblings.getLength();
    
    for(int i = 0; i < siblingCount; i++) {
      Node sibling = siblings.item(i);
      
      if(sibling == node) {
        break;
      }
      count++;
    }
    
    return count;
  }
  /**
   * Count the DOM nodes between the supplied sibling nodes, not including 
   * the nodes themselves.
   * <p/>
   * Counts the sibling nodes.
   * @param node1 First sibling node.
   * @param node2 Second sibling node.
   * @return The number of siblings between the supplied sibling nodes.
   * @throws UnsupportedOperationException if the supplied {@link Node Nodes}
   * don"t have the same parent node i.e. are not sibling nodes.
   */
  public static int countNodesBetween(Node node1, Node node2) {
    Node parent1 = node1.getParentNode();
        if(parent1 == null) {
          System.out.println("Cannot count nodes between [" + node1 + "] and [" + node2 + "]. [" + node1 + "] has no parent.");
      return 0;
    }
    
    Node parent2 = node2.getParentNode();
        if(parent2 == null) {
          System.out.println("Cannot count nodes between [" + node1 + "] and [" + node2 + "]. [" + node2 + "] has no parent.");
      return 0;
    }
    
    if(parent1 != parent2) {
      System.out.println("Cannot count nodes between [" + node1 + "] and [" + node2 + "]. These nodes do not share the same sparent.");
      return 0;
    }
    
    int countBeforeNode1 = countNodesBefore(node1);
    int countBeforeNode2 = countNodesBefore(node2);
    int count = countBeforeNode2 - countBeforeNode1 - 1;
    
    return count;
  }
  /**
   * Count the DOM element nodes before the supplied node, having the specified 
   * tag name, not including the node itself.
   * <p/>
   * Counts the sibling nodes.
   * @param node Node whose element siblings are to be counted.
   * @param tagName The tag name of the sibling elements to be counted. 
   * @return The number of siblings elements before the supplied node with the 
   * specified tag name.
   */
  public static int countElementsBefore(Node node, String tagName) {
    Node parent = node.getParentNode();
    if(parent == null) {
      System.out.println("Cannot count nodes before [" + node + "]. [" + node + "] has no parent.");
      return 0;
    }
    
    NodeList siblings = parent.getChildNodes();
    int count = 0;
    int siblingCount = siblings.getLength();
    
    for(int i = 0; i < siblingCount; i++) {
      Node sibling = siblings.item(i);
      
      if(sibling == node) {
        break;
      }
      if(sibling.getNodeType() == Node.ELEMENT_NODE && ((Element)sibling).getTagName().equals(tagName)) {
        count++;
      }     
    }
    
    return count;
  }
  /**
   * Get all the text DOM sibling nodes before the supplied node and 
   * concatenate them together into a single String.
   * @param node Text node.
   * @return String containing the concatentated text.
   */
  public static String getTextBefore(Node node) {
    Node parent = node.getParentNode();
    if(parent == null) {
      System.out.println("Cannot get text before node [" + node + "]. [" + node + "] has no parent.");
      return "";
    }
    
    NodeList siblings = parent.getChildNodes();
    StringBuffer text = new StringBuffer();
    int siblingCount = siblings.getLength();
    
    for(int i = 0; i < siblingCount; i++) {
      Node sibling = siblings.item(i);
      
      if(sibling == node) {
        break;
      }
      if(sibling.getNodeType() == Node.TEXT_NODE) {
        text.append(((Text)sibling).getData());
      }     
    }
    
    return text.toString();
  }
  /**
   * Get all the text DOM sibling nodes before the supplied node and 
   * concatenate them together into a single String.
   * @param node1 Test node.
   * @return String containing the concatentated text.
   */
  public static String getTextBetween(Node node1, Node node2) {
    Node parent1 = node1.getParentNode();
        if(parent1 == null) {
      System.out.println("Cannot get text between nodes [" + node1 + "] and [" + node2 + "]. [" + node1 + "] has no parent.");
      return "";
    }
    
    Node parent2 = node2.getParentNode();
        if(parent2 == null) {
          System.out.println("Cannot get text between nodes [" + node1 + "] and [" + node2 + "]. [" + node2 + "] has no parent.");
      return "";
    }
    
    if(parent1 != parent2) {
      System.out.println("Cannot get text between nodes [" + node1 + "] and [" + node2 + "]. These nodes do not share the same sparent.");
      return "";
    }
    NodeList siblings = parent1.getChildNodes();
    StringBuffer text = new StringBuffer();
    boolean append = false;
    int siblingCount = siblings.getLength();
    
    for(int i = 0; i < siblingCount; i++) {
      Node sibling = siblings.item(i);
      
      if(sibling == node1) {
        append = true;
      }
      if(sibling == node2) {
        break;
      }
      if(append && sibling.getNodeType() == Node.TEXT_NODE) {
        text.append(((Text)sibling).getData());
      }     
    }
    
    return text.toString();
  }
  
  /**
   * Construct the XPath of the supplied DOM Node.
   * <p/>
   * Supports element, comment and cdata sections DOM Node types.
   * @param node DOM node for XPath generation.
   * @return XPath string representation of the supplied DOM Node.
   */
  public static String getXPath(Node node) {

    StringBuffer xpath = new StringBuffer();
    Node parent = node.getParentNode();
    
    switch (node.getNodeType()) {
    case Node.ELEMENT_NODE:
      xpath.append(getXPathToken((Element)node));
      break;
    case Node.ruMENT_NODE:
      int commentNum = DomUtils.countNodesBefore(node, Node.ruMENT_NODE);
      xpath.append("/{COMMENT}[" + commentNum + 1 + "]");
      break;
    case Node.CDATA_SECTION_NODE:
      int cdataNum = DomUtils.countNodesBefore(node, Node.CDATA_SECTION_NODE);
      xpath.append("/{CDATA}[" + cdataNum + 1 + "]");
      break;
    default:
      throw new UnsupportedOperationException("XPath generation for supplied DOM Node type not supported.  Only supports element, comment and cdata section DOM nodes.");
    }
    while(parent != null && parent.getNodeType() == Node.ELEMENT_NODE) {
      xpath.insert(0, getXPathToken((Element)parent));      
      parent = parent.getParentNode();
    }
    return xpath.toString();
  }
  private static String getXPathToken(Element element) {

    String tagName = element.getTagName();
    int count = DomUtils.countElementsBefore(element, tagName);
    String xpathToken;
    
    if(count > 0) {
      xpathToken = "/" + tagName + "[" + (count + 1) + "]";
    } else {
      xpathToken = "/" + tagName;
    }
    
    return xpathToken;
  }
    public static int getDepth(Element element) {
        Node parent = element.getParentNode();
        int depth = 0;
        while(parent != null && parent.getNodeType() == Node.ELEMENT_NODE) {
            depth++;
            parent = parent.getParentNode();
        }
        return depth;
    }
  /**
   * Add literal text to the supplied element.
   * @param element Target DOM Element.
   * @param literalText Literal text to be added.
   */
  public static void addLiteral(Element element, String literalText) {
    
    Document document = element.getOwnerDocument();
    Text literal = document.createTextNode(literalText);
    element.appendChild(literal);
  }
  /**
   * Get the child element having the supplied localname, position
   * and namespace.
   * <p/>
   * Can be used instead of XPath.
   * @param parent Parent element to be searched.
   * @param localname Localname of the element required.
   * @param position The position of the element relative to other sibling
   * elements having the same name (and namespace if specified) e.g. if
   * searching for the 2nd &ltinput&gt; element, this param needs to
   * have a value of 2. 
     * @return The element at the requested position, or null if no such child
     * element exists on the parent element.
   */
  public static Element getElement(Element parent, String localname, int position) {
    return getElement(parent, localname, position, null);
  }
  /**
   * Get the child element having the supplied localname, position
   * and namespace.
   * <p/>
   * Can be used instead of XPath.
   * @param parent Parent element to be searched.
   * @param localname Localname of the element required.
   * @param position The position of the element relative to other sibling
   * elements having the same name (and namespace if specified) e.g. if
   * searching for the 2nd &ltinput&gt; element, this param needs to
   * have a value of 2. 
   * @param namespaceURI Namespace URI of the required element, or null
   * if a namespace comparison is not to be performed.
   * @return The element at the requested position, or null if no such child
   * element exists on the parent element.
   */
  public static Element getElement(Element parent, String localname, int position, String namespaceURI) {
    List elements = getElements(parent, localname, namespaceURI);
    position = Math.max(position, 1);
    if(position > elements.size()) {
      return null;
    }
    
    return (Element)elements.get(position - 1);
  }
  /**
   * Get the child elements having the supplied localname and namespace.
   * <p/>
   * Can be used instead of XPath.
   * @param parent Parent element to be searched.
   * @param localname Localname of the element required.  Supports "*" wildcards.
   * @param namespaceURI Namespace URI of the required element, or null
   * if a namespace comparison is not to be performed.
   * @return A list of W3C DOM {@link Element}s.  An empty list if no such
   * child elements exist on the parent element.
   */
  public static List getElements(Element parent, String localname, String namespaceURI) {
    
    return getElements(parent.getChildNodes(), localname, namespaceURI);
  }
  /**
   * Get the child elements having the supplied localname and namespace.
   * <p/>
   * Can be used instead of XPath.
   * @param nodeList List of DOM nodes on which to perform the search.
   * @param localname Localname of the element required.  Supports "*" wildcards.
   * @param namespaceURI Namespace URI of the required element, or null
   * if a namespace comparison is not to be performed.
   * @return A list of W3C DOM {@link Element}s.  An empty list if no such
   * child elements exist on the parent element.
   */
  public static List getElements(NodeList nodeList, String localname, String namespaceURI) {

    int count = nodeList.getLength();
    Vector elements = new Vector();
    
    for(int i = 0; i < count; i++) {
      Node node = nodeList.item(i);
      
      if(node.getNodeType() == Node.ELEMENT_NODE) {
        Element element = (Element)node;
        if(localname.equals("*") || getName(element).equals(localname)) {
          // The local name matches the element we"re after...
          if(namespaceURI == null || namespaceURI.equals(element.getNamespaceURI())) {
            elements.add(element);
          }
        }
      }
    }
    
    return elements;
  }
}





XML Document information by DOM

    
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XMLInfo {
  public static void main(String args[]) {
    try {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document document = builder.parse("xmlFileName.xml");
      Node root = document.getDocumentElement();
      System.out.print("Here is the document"s root node:");
      System.out.println(" " + root.getNodeName());
      System.out.println("Here are its child elements: ");
      NodeList childNodes = root.getChildNodes();
      Node currentNode;
      for (int i = 0; i < childNodes.getLength(); i++) {
        currentNode = childNodes.item(i);
        System.out.println(currentNode.getNodeName());
      }
      // get first child of root element
      currentNode = root.getFirstChild();
      System.out.print("The first child of root node is: ");
      System.out.println(currentNode.getNodeName());
      // get next sibling of first child
      System.out.print("whose next sibling is: ");
      currentNode = currentNode.getNextSibling();
      System.out.println(currentNode.getNodeName());
      // print value of next sibling of first child
      System.out.println("value of " + currentNode.getNodeName() + " element is: "
          + currentNode.getFirstChild().getNodeValue());
      // print name of parent of next sibling of first child
      System.out.print("Parent node of " + currentNode.getNodeName() + " is: "
          + currentNode.getParentNode().getNodeName());
    }
    // handle exception creating DocumentBuilder
    catch (ParserConfigurationException parserError) {
      System.err.println("Parser Configuration Error");
      parserError.printStackTrace();
    }
    // handle exception reading data from file
    catch (IOException fileException) {
      System.err.println("File IO Error");
      fileException.printStackTrace();
    }
    // handle exception parsing XML document
    catch (SAXException parseException) {
      System.err.println("Error Parsing Document");
      parseException.printStackTrace();
    }
  }
}





XML DOM Utilities

   
import java.io.OutputStream;
import java.io.Writer;
import java.util.Vector;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
//<p></p><p></p><p></p><p></p>
public class XMLUtils {
  public static DocumentBuilder getDOMBuilder() throws ParserConfigurationException {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    return dbf.newDocumentBuilder();
  }
  public static Transformer getTransformer() throws TransformerConfigurationException {
    TransformerFactory tf = TransformerFactory.newInstance();
    return tf.newTransformer();
  }
  public static Document createDocument() throws ParserConfigurationException {
    return XMLUtils.getDOMBuilder().newDocument();
  }
  public static Element firstChildElement(Node node) {
    for (Node tempNode = node.getFirstChild(); tempNode != null; tempNode = tempNode
        .getNextSibling()) {
      if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
        return (Element) tempNode;
      }
    }
    return null;
  }
  public static Element nextSiblingElement(Node node) {
    for (Node tempNode = node.getNextSibling(); tempNode != null; tempNode = tempNode
        .getNextSibling()) {
      if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
        return (Element) tempNode;
      }
    }
    return null;
  }
  public static Element lastChildElement(Node node) {
    for (Node tempNode = node.getLastChild(); tempNode != null; tempNode = tempNode
        .getPreviousSibling()) {
      if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
        return (Element) tempNode;
      }
    }
    return null;
  }
  public static Element previousSiblingElement(Node node) {
    for (Node tempNode = node.getPreviousSibling(); tempNode != null; tempNode = tempNode
        .getPreviousSibling()) {
      if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
        return (Element) tempNode;
      }
    }
    return null;
  }
  public static Vector getAllChildElements(Node node) {
    Vector v = new Vector();
    Node child = XMLUtils.firstChildElement(node);
    while (child != null) {
      v.add(child);
      child = XMLUtils.nextSiblingElement(child);
    }
    return v;
  }
  public static Vector getChildElementsByNS(Node node, String uri, String localName) {
    Vector childElements = XMLUtils.getAllChildElements(node);
    Vector v = new Vector();
    for (int i = 0; i < childElements.size(); i++) {
      Element child = (Element) childElements.get(i);
      String ln = child.getLocalName();
      String u = child.getNamespaceURI();
      if (uri == null) {
        if (ln.equals(localName)) {
          v.add(child);
        }
      } else {
        if (ln.equals(localName) && u.equals(uri)) {
          v.add(child);
        }
      }
    }
    return v;
  }
  public static String getLocalName(String nodeName) {
    int index = nodeName.lastIndexOf(58);
    if (index == -1) {
      return nodeName;
    } else {
      return nodeName.substring(index + 1, nodeName.length());
    }
  }
  public static String getPrefix(String nodeName) {
    int index = nodeName.lastIndexOf(58);
    if (index == -1) {
      return null;
    } else {
      return nodeName.substring(0, index);
    }
  }
  public static void outDOMNode(Node node, Writer writer) throws TransformerConfigurationException,
      TransformerException {
    Transformer transformer = XMLUtils.getTransformer();
    Source source = new DOMSource(node);
    Result result = new StreamResult(writer);
    transformer.transform(source, result);
  }
  public static void outDOMNode(Node node, OutputStream os)
      throws TransformerConfigurationException, TransformerException {
    Transformer transformer = XMLUtils.getTransformer();
    Source source = new DOMSource(node);
    Result result = new StreamResult(os);
    transformer.transform(source, result);
  }
}