Java Tutorial/XML/DOM Tree

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

Accessing different types of DOM tree nodes

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





Copying a Subtree of Nodes from One DOM Document to Another

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





Copying a Subtree of Nodes in a DOM Document

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





Create new DOM tree with fully qualified element names

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





Creating a new DOM tree

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class Main {
  public static void main(String[] argv) throws Exception {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder loader = factory.newDocumentBuilder();
    Document document = loader.newDocument();
    Element root = document.createElement("order");
    document.appendChild(root);
  }
}





Custom complex filters for selecting nodes

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.traversal.DocumentTraversal;
import org.w3c.dom.traversal.NodeFilter;
import org.w3c.dom.traversal.NodeIterator;
public class Main {
  public static void main(String[] argv) throws Exception {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder loader = factory.newDocumentBuilder();
    Document document = loader.parse("sample.xml");
    DocumentTraversal traversal = (DocumentTraversal) document;
    NodeIterator iterator = traversal.createNodeIterator(document.getDocumentElement(),
        NodeFilter.SHOW_ALL, new ItemFilter(), true);
    for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) {
      System.out.println("Element: " + ((Element) n).getTagName());
    }
  }
  private static final class ItemFilter implements NodeFilter {
    public short acceptNode(Node n) {
      if (n instanceof Element) {
        if (((Element) n).getTagName().equals("item")) {
          return NodeFilter.FILTER_ACCEPT;
        }
      }
      return NodeFilter.FILTER_REJECT;
    }
  }
}





Generates a DOM from scratch. Writes the DOM to a String using an LSSerializer.

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;
/**
 * Simple Sample that: - Generates a DOM from scratch. - Writes the DOM to a
 * String using an LSSerializer
 * 
 * @author Jeffrey Rodriguez
 * @version $Id: DOMGenerate.java 546623 2007-06-12 20:25:08Z mrglavas $
 */
public class DOMGenerate {
  public static void main(String[] argv) {
    try {
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      dbf.setNamespaceAware(true);
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.newDocument();
      Element root = doc.createElementNS(null, "person"); // Create Root Element
      Element item = doc.createElementNS(null, "name"); // Create element
      item.appendChild(doc.createTextNode("Jeff"));
      root.appendChild(item); // Attach element to Root element
      item = doc.createElementNS(null, "age"); // Create another Element
      item.appendChild(doc.createTextNode("28"));
      root.appendChild(item); // Attach Element to previous element down tree
      item = doc.createElementNS(null, "height");
      item.appendChild(doc.createTextNode("1.80"));
      root.appendChild(item); // Attach another Element - grandaugther
      doc.appendChild(root); // Add Root to Document
      DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
      DOMImplementationLS domImplLS = (DOMImplementationLS) registry.getDOMImplementation("LS");
      LSSerializer ser = domImplLS.createLSSerializer(); // Create a serializer
                                                          // for the DOM
      LSOutput out = domImplLS.createLSOutput();
      StringWriter stringOut = new StringWriter(); // Writer will be a String
      out.setCharacterStream(stringOut);
      ser.write(doc, out); // Serialize the DOM
      System.out.println("STRXML = " + stringOut.toString()); // Spit out the
                                                              // DOM as a String
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}





Get this Document"s root node

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

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





Print Tree node

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/*
 * Copyright 2005 Joe Walker
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * 
 * @author Abey Mullassery
 * 
 */
public class Main {
  public static void printTree(Node doc) {
    if (doc == null) {
      System.out.println("Nothing to print!!");
      return;
    }
    try {
      System.out.println(doc.getNodeName() + "  " + doc.getNodeValue());
      NamedNodeMap cl = doc.getAttributes();
      for (int i = 0; i < cl.getLength(); i++) {
        Node node = cl.item(i);
        System.out.println(
          "\t" + node.getNodeName() + " ->" + node.getNodeValue());
      }
      NodeList nl = doc.getChildNodes();
      for (int i = 0; i < nl.getLength(); i++) {
        Node node = nl.item(i);
        printTree(node);
      }
    } catch (Throwable e) {
      System.out.println("Cannot print!! " + e.getMessage());
    }
  }
}





Reading a DOM tree from XML document

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





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

/*
 *
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights 
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:  
 *       "This product includes software developed by the 
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written 
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS"" AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
// $Id: DOMWriter.java 2891 2008-07-31 16:03:02Z thomas.diesler@jboss.ru $
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
 * Traverse a DOM tree in order to print a document that is parsed.
 * 
 * @author Andy Clark, IBM
 * @author Thomas.Diesler@jboss.org
 */
@SuppressWarnings("unchecked")
public class DOMWriter {
  // Print writer
  private PrintWriter out;
  // True, if canonical output
  private boolean canonical;
  // True, if pretty printing should be used
  private boolean prettyprint;
  // True, if the XML declaration should be written
  private boolean writeXMLDeclaration;
  // True, if whitespace should be ignored
  private boolean ignoreWhitespace;
  // Explicit character set encoding
  private String charsetName;
  // indent for the pretty printer
  private int prettyIndent;
  // True, if the XML declaration has been written
  private boolean wroteXMLDeclaration;
  // The node that started the write
  private Node rootNode;
  // True if we want namespace completion
  private boolean completeNamespaces = true;
  // The current default namespace
  private String currentDefaultNamespace;
  public DOMWriter(Writer w) {
    this.out = new PrintWriter(w);
  }
  public DOMWriter(Writer w, String charsetName) {
    this.out = new PrintWriter(w);
    this.charsetName = charsetName;
    this.writeXMLDeclaration = true;
  }
  public DOMWriter(OutputStream stream) {
    try {
      this.out = new PrintWriter(new OutputStreamWriter(stream, "UTF-8"));
    } catch (UnsupportedEncodingException e) {
      // ignore, UTF-8 should be available
    }
  }
  public DOMWriter(OutputStream stream, String charsetName) {
    try {
      this.out = new PrintWriter(new OutputStreamWriter(stream, charsetName));
      this.charsetName = charsetName;
      this.writeXMLDeclaration = true;
    } catch (UnsupportedEncodingException e) {
      throw new IllegalArgumentException("Unsupported encoding: " + charsetName);
    }
  }
  /**
   * Print a node with explicit prettyprinting. The defaults for all other
   * DOMWriter properties apply.
   * 
   */
  public static String printNode(Node node, boolean prettyprint) {
    StringWriter strw = new StringWriter();
    new DOMWriter(strw).setPrettyprint(prettyprint).print(node);
    return strw.toString();
  }
  public boolean isCanonical() {
    return canonical;
  }
  /**
   * Set wheter entities should appear in their canonical form. The default is
   * false.
   */
  public DOMWriter setCanonical(boolean canonical) {
    this.canonical = canonical;
    return this;
  }
  public boolean isIgnoreWhitespace() {
    return ignoreWhitespace;
  }
  /**
   * Set whether whitespace should be ignored. The default is false.
   */
  public DOMWriter setIgnoreWhitespace(boolean ignoreWhitespace) {
    this.ignoreWhitespace = ignoreWhitespace;
    return this;
  }
  /**
   * Set wheter subelements should have their namespaces completed. Setting this
   * to false may lead to invalid XML fragments. The default is true.
   */
  public DOMWriter setCompleteNamespaces(boolean complete) {
    this.rupleteNamespaces = complete;
    return this;
  }
  public boolean isPrettyprint() {
    return prettyprint;
  }
  /**
   * Set wheter element should be indented. The default is false.
   */
  public DOMWriter setPrettyprint(boolean prettyprint) {
    this.prettyprint = prettyprint;
    return this;
  }
  public boolean isWriteXMLDeclaration() {
    return writeXMLDeclaration;
  }
  /**
   * Set wheter the XML declaration should be written. The default is false.
   */
  public DOMWriter setWriteXMLDeclaration(boolean flag) {
    this.writeXMLDeclaration = flag;
    return this;
  }
  public void print(Node node) {
    if (prettyprint && ignoreWhitespace)
      throw new IllegalStateException("Cannot pretty print and ignore whitespace");
    rootNode = node;
    printInternal(node, false);
  }
  private void printInternal(Node node, boolean indentEndMarker) {
    // is there anything to do?
    if (node == null) {
      return;
    }
    // JBAS-2117 - Don"t skip the DOCUMENT_NODE
    // if (node instanceof Document) node =
    // ((Document)node).getDocumentElement();
    if (wroteXMLDeclaration == false && writeXMLDeclaration == true && canonical == false) {
      out.print("<?xml version="1.0"");
      if (charsetName != null)
        out.print(" encoding="" + charsetName + """);
      out.print("?>");
      if (prettyprint)
        out.println();
      wroteXMLDeclaration = true;
    }
    int type = node.getNodeType();
    boolean hasChildNodes = node.getChildNodes().getLength() > 0;
    String nodeName = node.getNodeName();
    switch (type) {
    // print document
    case Node.DOCUMENT_NODE: {
      NodeList children = node.getChildNodes();
      for (int iChild = 0; iChild < children.getLength(); iChild++) {
        printInternal(children.item(iChild), false);
      }
      out.flush();
      break;
    }
    // print element with attributes
    case Node.ELEMENT_NODE: {
      Element element = (Element) node;
      if (prettyprint) {
        for (int i = 0; i < prettyIndent; i++) {
          out.print(" ");
        }
        prettyIndent++;
      }
      out.print("<");
      out.print(nodeName);
      Map nsMap = new HashMap();
      String elPrefix = node.getPrefix();
      String elNamespaceURI = node.getNamespaceURI();
      if (elPrefix != null) {
        String nsURI = getNamespaceURI(elPrefix, element, rootNode);
        nsMap.put(elPrefix, nsURI);
      }
      Attr attrs[] = sortAttributes(node.getAttributes());
      for (int i = 0; i < attrs.length; i++) {
        Attr attr = attrs[i];
        String atPrefix = attr.getPrefix();
        String atName = attr.getNodeName();
        String atValue = normalize(attr.getNodeValue(), canonical);
        if (atName.equals("xmlns"))
          currentDefaultNamespace = atValue;
        if (atPrefix != null && !atPrefix.equals("xmlns") && !atPrefix.equals("xml")) {
          String nsURI = getNamespaceURI(atPrefix, element, rootNode);
          nsMap.put(atPrefix, nsURI);
          // xsi:type="ns1:SubType", xsi:type="xsd:string"
          if (atName.equals(atPrefix + ":type") && atValue.indexOf(":") > 0) {
            // xsi defined on the envelope
            if (nsURI == null)
              nsURI = getNamespaceURI(atPrefix, element, null);
            if ("http://www.w3.org/2001/XMLSchema-instance".equals(nsURI)) {
              String typePrefix = atValue.substring(0, atValue.indexOf(":"));
              String typeURI = getNamespaceURI(typePrefix, element, rootNode);
              nsMap.put(typePrefix, typeURI);
            }
          }
        }
        out.print(" " + atName + "="" + atValue + """);
      }
      // Add namespace declaration for prefixes
      // that are defined further up the tree
      if (completeNamespaces) {
        Iterator itPrefix = nsMap.keySet().iterator();
        while (itPrefix.hasNext()) {
          String prefix = (String) itPrefix.next();
          String nsURI = (String) nsMap.get(prefix);
          if (nsURI == null) {
            nsURI = getNamespaceURI(prefix, element, null);
            out.print(" xmlns:" + prefix + "="" + nsURI + """);
          }
        }
      }
      // The SAX ContentHandler will by default not add the namespace
      // declaration
      // <Hello xmlns="http://somens">World</Hello>
      if (elPrefix == null && elNamespaceURI != null) {
        String defaultNamespace = element.getAttribute("xmlns");
        if (defaultNamespace.length() == 0 && !elNamespaceURI.equals(currentDefaultNamespace)) {
          out.print(" xmlns="" + elNamespaceURI + """);
          currentDefaultNamespace = elNamespaceURI;
        }
      }
      if (hasChildNodes) {
        out.print(">");
      }
      // Find out if the end marker is indented
      indentEndMarker = isEndMarkerIndented(node);
      if (indentEndMarker) {
        out.print("\n");
      }
      NodeList childNodes = node.getChildNodes();
      int len = childNodes.getLength();
      for (int i = 0; i < len; i++) {
        Node childNode = childNodes.item(i);
        printInternal(childNode, false);
      }
      break;
    }
    // handle entity reference nodes
    case Node.ENTITY_REFERENCE_NODE: {
      if (canonical) {
        NodeList children = node.getChildNodes();
        if (children != null) {
          int len = children.getLength();
          for (int i = 0; i < len; i++) {
            printInternal(children.item(i), false);
          }
        }
      } else {
        out.print("&");
        out.print(nodeName);
        out.print(";");
      }
      break;
    }
    // print cdata sections
    case Node.CDATA_SECTION_NODE: {
      if (canonical) {
        out.print(normalize(node.getNodeValue(), canonical));
      } else {
        out.print("<![CDATA[");
        out.print(node.getNodeValue());
        out.print("]]&gt;");
      }
      break;
    }
    // print text
    case Node.TEXT_NODE: {
      String text = normalize(node.getNodeValue(), canonical);
      if (text.trim().length() > 0) {
        out.print(text);
      } else if (prettyprint == false && ignoreWhitespace == false) {
        out.print(text);
      }
      break;
    }
    // print processing instruction
    case Node.PROCESSING_INSTRUCTION_NODE: {
      out.print("<?");
      out.print(nodeName);
      String data = node.getNodeValue();
      if (data != null && data.length() > 0) {
        out.print(" ");
        out.print(data);
      }
      out.print("?>");
      break;
    }
    // print comment
    case Node.ruMENT_NODE: {
      for (int i = 0; i < prettyIndent; i++) {
        out.print(" ");
      }
      out.print("<!--");
      String data = node.getNodeValue();
      if (data != null) {
        out.print(data);
      }
      out.print("-->");
      if (prettyprint) {
        out.print("\n");
      }
      break;
    }
    }
    if (type == Node.ELEMENT_NODE) {
      if (prettyprint)
        prettyIndent--;
      if (hasChildNodes == false) {
        out.print("/>");
      } else {
        if (indentEndMarker) {
          for (int i = 0; i < prettyIndent; i++) {
            out.print(" ");
          }
        }
        out.print("</");
        out.print(nodeName);
        out.print(">");
      }
      if (prettyIndent > 0) {
        out.print("\n");
      }
    }
    out.flush();
  }
  private String getNamespaceURI(String prefix, Element element, Node stopNode) {
    Node parent = element.getParentNode();
    String nsURI = element.getAttribute("xmlns:" + prefix);
    if (nsURI.length() == 0 && element != stopNode && parent instanceof Element)
      return getNamespaceURI(prefix, (Element) parent, stopNode);
    return (nsURI.length() > 0 ? nsURI : null);
  }
  private boolean isEndMarkerIndented(Node node) {
    if (prettyprint) {
      NodeList childNodes = node.getChildNodes();
      int len = childNodes.getLength();
      for (int i = 0; i < len; i++) {
        Node children = childNodes.item(i);
        if (children.getNodeType() == Node.ELEMENT_NODE) {
          return true;
        }
      }
    }
    return false;
  }
  /** Returns a sorted list of attributes. */
  private Attr[] sortAttributes(NamedNodeMap attrs) {
    int len = (attrs != null) ? attrs.getLength() : 0;
    Attr array[] = new Attr[len];
    for (int i = 0; i < len; i++) {
      array[i] = (Attr) attrs.item(i);
    }
    for (int i = 0; i < len - 1; i++) {
      String name = array[i].getNodeName();
      int index = i;
      for (int j = i + 1; j < len; j++) {
        String curName = array[j].getNodeName();
        if (curName.rupareTo(name) < 0) {
          name = curName;
          index = j;
        }
      }
      if (index != i) {
        Attr temp = array[i];
        array[i] = array[index];
        array[index] = temp;
      }
    }
    return (array);
  }
  /** Normalizes the given string. */
  public static String normalize(String s, boolean canonical) {
    StringBuffer str = new StringBuffer();
    int len = (s != null) ? s.length() : 0;
    for (int i = 0; i < len; i++) {
      char ch = s.charAt(i);
      switch (ch) {
      case "<": {
        str.append("&lt;");
        break;
      }
      case ">": {
        str.append("&gt;");
        break;
      }
      case "&": {
        str.append("&amp;");
        break;
      }
      case """: {
        str.append("&quot;");
        break;
      }
      case "\"": {
        str.append("&apos;");
        break;
      }
      case "\r":
      case "\n": {
        if (canonical) {
          str.append("&#");
          str.append(Integer.toString(ch));
          str.append(";");
          break;
        }
        // else, default append char
      }
      default: {
        str.append(ch);
      }
      }
    }
    return (str.toString());
  }
}





Traverse the DOM tree as a list

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





Traverse the DOM tree using TreeWalker

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





Using ranges in DOM tree

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