Java/XML/DOM Tree
Содержание
- 1 Accessing different types of DOM tree nodes
- 2 Copying a Subtree of Nodes from One DOM Document to Another
- 3 Copying a Subtree of Nodes in a DOM Document
- 4 Create new DOM tree with fully qualified element names
- 5 Creating a new DOM tree
- 6 DOM Util: get Child Text
- 7 Get Child Content
- 8 Gets the child of the specified element having the specified name. If the child with this name doesn"t exist then null is returned instead.
- 9 Gets the child of the specified element having the specified unique name
- 10 Get the first child of the specified type.
- 11 Get the first child"s content ( ie it"s included TEXT node ).
- 12 Get the first direct child with a given type
- 13 Get this Document"s root node
- 14 Manipulate w3c DOM trees
- 15 Print Tree node
- 16 Reading a DOM tree from XML document
- 17 Returns an iterator over the children of the given element with the given tag name
- 18 Returns the concatenated child text of the specified node.
- 19 Return the next sibling with a given name and type
- 20 Saving a DOM tree to XML file javax.xml.parsers (JAXP)
- 21 Search earlier siblings for a given node
- 22 Search for a named child of a given node
- 23 Search our next siblings for a given node
- 24 Search up the tree for a given node
- 25 Traverse a DOM tree in order to get information about the document.
- 26 Traverse a DOM tree in order to print a document that is parsed.
- 27 Traverse the DOM tree as a list
- 28 Traverse the DOM tree using TreeWalker
- 29 Using ranges in DOM tree
Accessing different types of DOM tree nodes
<source lang="java">
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Attr; import org.w3c.dom.CharacterData; import org.w3c.dom.rument; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; public class Main {
public static void main(String[] argv) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder loader = factory.newDocumentBuilder(); Document document = loader.parse("sample.xml"); Element purchaseOrder = document.getDocumentElement(); printElement(purchaseOrder, ""); } static void printElement(Element element, String indent) { System.out.println("Element "" + element.getNodeName() + """); NodeList children = element.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); switch (child.getNodeType()) { case Node.ELEMENT_NODE: printElement((Element) child, indent + "\t"); break; case Node.ATTRIBUTE_NODE: Attr attr = (Attr) child; System.out.println("\tAttribute: "" + attr.getName() + "" = "" + attr.getValue() + """); break; case Node.ruMENT_NODE: Comment comment = (Comment) child; System.out.println("\tComment: "" + comment.getData() + """); break; case Node.CDATA_SECTION_NODE: CharacterData cdata = (CharacterData) child; System.out.println("\tCDatat: "" + cdata.getData() + """); break; case Node.TEXT_NODE: Text text = (Text) child; System.out.println("\tText: "" + text.getData() + """); break; default: System.out.println("\tUnknown node type: "" + child.getNodeType() + """); break; } } }
}
</source>
Copying a Subtree of Nodes from One DOM Document to Another
<source lang="java">
import java.io.File; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class Main {
public static void main(String[] argv) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); factory.setExpandEntityReferences(false); Document doc1 = factory.newDocumentBuilder().parse(new File("filename")); NodeList list = doc1.getElementsByTagName("entry"); Element element = (Element) list.item(0); Document doc2 = factory.newDocumentBuilder().parse(new File("infilename2.xml")); Node dup = doc2.importNode(element, true); doc2.getDocumentElement().appendChild(dup); }
}
</source>
Copying a Subtree of Nodes in a DOM Document
<source lang="java">
import java.io.File; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; public class Main {
public static void main(String[] argv) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(true); factory.setExpandEntityReferences(false); Document doc = factory.newDocumentBuilder().parse(new File("filename")); NodeList list = doc.getElementsByTagName("entry"); Element element = (Element) list.item(0); Element dup = (Element) element.cloneNode(true); element.getParentNode().insertBefore(dup, element.getNextSibling()); }
}
</source>
Create new DOM tree with fully qualified element names
<source lang="java">
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; public class Main {
public static void main(String[] argv) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder loader = factory.newDocumentBuilder(); Document document = loader.newDocument(); String docNS = "http://www.my-company.ru"; Element order = document.createElementNS(docNS, "order"); document.appendChild(order); order.setAttribute("xmlns", docNS); }
}
</source>
Creating a new DOM tree
<source lang="java">
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; public class Main {
public static void main(String[] argv) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder loader = factory.newDocumentBuilder(); Document document = loader.newDocument(); Element root = document.createElement("order"); document.appendChild(root); }
}
</source>
DOM Util: get Child Text
<source lang="java">
import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class Main {
public static String getChildText(Element parent, String childName) { NodeList list = parent.getElementsByTagName(childName); if (list.getLength() > 1) { throw new IllegalStateException("Multiple child elements with name " + childName); } else if (list.getLength() == 0) { return null; } Element child = (Element) list.item(0); return getText(child); } public static String getText(Element element) { StringBuffer buf = new StringBuffer(); NodeList list = element.getChildNodes(); boolean found = false; for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); if (node.getNodeType() == Node.TEXT_NODE) { buf.append(node.getNodeValue()); found = true; } } return found ? buf.toString() : null; }
}
</source>
Get Child Content
<source lang="java">
import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class Main {
public static String getChildContent(Element parent, String name, String missing, String empty) { Element child = getChild(parent, name); if (child == null) { return missing; } else { String content = (String) getContent(child); return (content != null) ? content : empty; } } public static Object getContent(Element element) { NodeList nl = element.getChildNodes(); StringBuffer content = new StringBuffer(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); switch (node.getNodeType()) { case Node.ELEMENT_NODE: return node; case Node.CDATA_SECTION_NODE: case Node.TEXT_NODE: content.append(node.getNodeValue()); break; } } return content.toString().trim(); } public static Element getChild(Element parent, String name) { for (Node child = parent.getFirstChild(); child != null; child = child.getNextSibling()) { if (child instanceof Element && name.equals(child.getNodeName())) { return (Element) child; } } return null; }
}
</source>
Gets the child of the specified element having the specified name. If the child with this name doesn"t exist then null is returned instead.
<source lang="java">
import java.util.ArrayList; import java.util.Iterator; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /**
* A utility class to cover up the rough bits of xml parsing * * @author * @version $Revision: 2787 $ */
@SuppressWarnings("unchecked") public class XmlHelper {
/** * Returns an iterator over the children of the given element with the given * tag name. * * @param element * The parent element * @param tagName * The name of the desired child * @return An interator of children or null if element is null. */ public static Iterator getChildrenByTagName(Element element, String tagName) { if (element == null) return null; // getElementsByTagName gives the corresponding elements in the whole // descendance. We want only children NodeList children = element.getChildNodes(); ArrayList goodChildren = new ArrayList(); for (int i = 0; i < children.getLength(); i++) { Node currentChild = children.item(i); if (currentChild.getNodeType() == Node.ELEMENT_NODE && ((Element) currentChild).getTagName().equals(tagName)) { goodChildren.add(currentChild); } } return goodChildren.iterator(); } /** * Gets the child of the specified element having the specified unique name. * If there are more than one children elements with the same name and * exception is thrown. * * @param element * The parent element * @param tagName * The name of the desired child * @return The named child. * * @throws Exception * Child was not found or was not unique. */ public static Element getUniqueChild(Element element, String tagName) throws Exception { Iterator goodChildren = getChildrenByTagName(element, tagName); if (goodChildren != null && goodChildren.hasNext()) { Element child = (Element) goodChildren.next(); if (goodChildren.hasNext()) { throw new Exception("expected only one " + tagName + " tag"); } return child; } else { throw new Exception("expected one " + tagName + " tag"); } } /** * Gets the child of the specified element having the specified name. If the * child with this name doesn"t exist then null is returned instead. * * @param element * the parent element * @param tagName * the name of the desired child * @return either the named child or null * @throws Exception */ public static Element getOptionalChild(Element element, String tagName) throws Exception { return getOptionalChild(element, tagName, null); } /** * Gets the child of the specified element having the specified name. If the * child with this name doesn"t exist then the supplied default element is * returned instead. * * @param element * the parent element * @param tagName * the name of the desired child * @param defaultElement * the element to return if the child doesn"t exist * @return either the named child or the supplied default * @throws Exception */ public static Element getOptionalChild(Element element, String tagName, Element defaultElement) throws Exception { Iterator goodChildren = getChildrenByTagName(element, tagName); if (goodChildren != null && goodChildren.hasNext()) { Element child = (Element) goodChildren.next(); if (goodChildren.hasNext()) { throw new Exception("expected only one " + tagName + " tag"); } return child; } else { return defaultElement; } } /** * Get the content of the given element. * * @param element * The element to get the content for. * @return The content of the element or null. * @throws Exception */ public static String getElementContent(final Element element) throws Exception { return getElementContent(element, null); } /** * Get the content of the given element. * * @param element * The element to get the content for. * @param defaultStr * The default to return when there is no content. * @return The content of the element or the default. * @throws Exception */ public static String getElementContent(Element element, String defaultStr) throws Exception { if (element == null) return defaultStr; NodeList children = element.getChildNodes(); String result = ""; for (int i = 0; i < children.getLength(); i++) { if (children.item(i).getNodeType() == Node.TEXT_NODE || children.item(i).getNodeType() == Node.CDATA_SECTION_NODE) { result += children.item(i).getNodeValue(); } else if (children.item(i).getNodeType() == Node.ruMENT_NODE) { // Ignore comment nodes } } return result.trim(); } /** * Macro to get the content of a unique child element. * * @param element * The parent element. * @param tagName * The name of the desired child. * @return The element content or null. * @throws Exception */ public static String getUniqueChildContent(Element element, String tagName) throws Exception { return getElementContent(getUniqueChild(element, tagName)); } /** * Macro to get the content of an optional child element. * * @param element * The parent element. * @param tagName * The name of the desired child. * @return The element content or null. * @throws Exception */ public static String getOptionalChildContent(Element element, String tagName) throws Exception { return getElementContent(getOptionalChild(element, tagName)); } public static boolean getOptionalChildBooleanContent(Element element, String name) throws Exception { Element child = getOptionalChild(element, name); if (child != null) { String value = getElementContent(child).toLowerCase(); return value.equals("true") || value.equals("yes"); } return false; }
}
</source>
Gets the child of the specified element having the specified unique name
<source lang="java">
import java.util.ArrayList; import java.util.Iterator; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /**
* A utility class to cover up the rough bits of xml parsing * * @author * @version $Revision: 2787 $ */
@SuppressWarnings("unchecked") public class XmlHelper {
/** * Returns an iterator over the children of the given element with the given * tag name. * * @param element * The parent element * @param tagName * The name of the desired child * @return An interator of children or null if element is null. */ public static Iterator getChildrenByTagName(Element element, String tagName) { if (element == null) return null; // getElementsByTagName gives the corresponding elements in the whole // descendance. We want only children NodeList children = element.getChildNodes(); ArrayList goodChildren = new ArrayList(); for (int i = 0; i < children.getLength(); i++) { Node currentChild = children.item(i); if (currentChild.getNodeType() == Node.ELEMENT_NODE && ((Element) currentChild).getTagName().equals(tagName)) { goodChildren.add(currentChild); } } return goodChildren.iterator(); } /** * Gets the child of the specified element having the specified unique name. * If there are more than one children elements with the same name and * exception is thrown. * * @param element * The parent element * @param tagName * The name of the desired child * @return The named child. * * @throws Exception * Child was not found or was not unique. */ public static Element getUniqueChild(Element element, String tagName) throws Exception { Iterator goodChildren = getChildrenByTagName(element, tagName); if (goodChildren != null && goodChildren.hasNext()) { Element child = (Element) goodChildren.next(); if (goodChildren.hasNext()) { throw new Exception("expected only one " + tagName + " tag"); } return child; } else { throw new Exception("expected one " + tagName + " tag"); } } /** * Gets the child of the specified element having the specified name. If the * child with this name doesn"t exist then null is returned instead. * * @param element * the parent element * @param tagName * the name of the desired child * @return either the named child or null * @throws Exception */ public static Element getOptionalChild(Element element, String tagName) throws Exception { return getOptionalChild(element, tagName, null); } /** * Gets the child of the specified element having the specified name. If the * child with this name doesn"t exist then the supplied default element is * returned instead. * * @param element * the parent element * @param tagName * the name of the desired child * @param defaultElement * the element to return if the child doesn"t exist * @return either the named child or the supplied default * @throws Exception */ public static Element getOptionalChild(Element element, String tagName, Element defaultElement) throws Exception { Iterator goodChildren = getChildrenByTagName(element, tagName); if (goodChildren != null && goodChildren.hasNext()) { Element child = (Element) goodChildren.next(); if (goodChildren.hasNext()) { throw new Exception("expected only one " + tagName + " tag"); } return child; } else { return defaultElement; } } /** * Get the content of the given element. * * @param element * The element to get the content for. * @return The content of the element or null. * @throws Exception */ public static String getElementContent(final Element element) throws Exception { return getElementContent(element, null); } /** * Get the content of the given element. * * @param element * The element to get the content for. * @param defaultStr * The default to return when there is no content. * @return The content of the element or the default. * @throws Exception */ public static String getElementContent(Element element, String defaultStr) throws Exception { if (element == null) return defaultStr; NodeList children = element.getChildNodes(); String result = ""; for (int i = 0; i < children.getLength(); i++) { if (children.item(i).getNodeType() == Node.TEXT_NODE || children.item(i).getNodeType() == Node.CDATA_SECTION_NODE) { result += children.item(i).getNodeValue(); } else if (children.item(i).getNodeType() == Node.ruMENT_NODE) { // Ignore comment nodes } } return result.trim(); } /** * Macro to get the content of a unique child element. * * @param element * The parent element. * @param tagName * The name of the desired child. * @return The element content or null. * @throws Exception */ public static String getUniqueChildContent(Element element, String tagName) throws Exception { return getElementContent(getUniqueChild(element, tagName)); } /** * Macro to get the content of an optional child element. * * @param element * The parent element. * @param tagName * The name of the desired child. * @return The element content or null. * @throws Exception */ public static String getOptionalChildContent(Element element, String tagName) throws Exception { return getElementContent(getOptionalChild(element, tagName)); } public static boolean getOptionalChildBooleanContent(Element element, String name) throws Exception { Element child = getOptionalChild(element, name); if (child != null) { String value = getElementContent(child).toLowerCase(); return value.equals("true") || value.equals("yes"); } return false; }
}
</source>
Get the first child of the specified type.
<source lang="java">
import org.w3c.dom.Node; public class Utils {
/** * Get the first child of the specified type. * * @param parent * @param type * @return */ public static Node getChild(Node parent, int type) { Node n = parent.getFirstChild(); while (n != null && type != n.getNodeType()) { n = n.getNextSibling(); } if (n == null) { return null; } return n; }
}
</source>
Get the first child"s content ( ie it"s included TEXT node ).
<source lang="java">
import org.w3c.dom.Node; /**
* * * @author Costin Manolache */
public class Main {
/** Get the first child"s content ( ie it"s included TEXT node ). */ public static String getChildContent( Node parent, String name ) { Node first=parent.getFirstChild(); if( first==null ) return null; for (Node node = first; node != null; node = node.getNextSibling()) { //System.out.println("getNode: " + name + " " + node.getNodeName()); if( name.equals( node.getNodeName() ) ) { return getContent( node ); } } return null; } /** Get the trimed text content of a node or null if there is no text */ public static String getContent(Node n ) { if( n==null ) return null; Node n1=getChild(n, Node.TEXT_NODE); if( n1==null ) return null; String s1=n1.getNodeValue(); return s1.trim(); } /** Get the first direct child with a given type */ public static Node getChild( Node parent, int type ) { Node n=parent.getFirstChild(); while( n!=null && type != n.getNodeType() ) { n=n.getNextSibling(); } if( n==null ) return null; return n; }
}
</source>
Get the first direct child with a given type
<source lang="java">
import org.w3c.dom.Node; /**
* * * @author Costin Manolache */
public class Main {
/** Get the first direct child with a given type */ public static Node getChild( Node parent, int type ) { Node n=parent.getFirstChild(); while( n!=null && type != n.getNodeType() ) { n=n.getNextSibling(); } if( n==null ) return null; return n; }
}
</source>
Get this Document"s root node
<source lang="java">
import org.w3c.dom.Document; import org.w3c.dom.Element;
public class Main {
// return this Document"s root node public static Element getRoot(Document doc) { return doc.getDocumentElement(); } // getRoot(Document(: Element
}
</source>
Manipulate w3c DOM trees
<source lang="java">
// // Copyright 2007 Requea. // ------------------------------------------------------------------------ // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //
import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.util.Stack; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.CDATASection; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException;
/**
* Utilities to manipulate w3c DOM trees. * @author Pierre Dubois */
public class XMLUtils {
private static DocumentBuilderFactory fDocumentFactory; private static Stack fParsersPool = new Stack(); /** * Public Id and the Resource path (of the cached copy) * of the DTDs for tag library descriptors. */ public static final String TAGLIB_DTD_PUBLIC_ID_11 = "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"; public static final String TAGLIB_DTD_RESOURCE_PATH_11 = "/javax/servlet/jsp/resources/web-jsptaglibrary_1_1.dtd"; public static final String TAGLIB_DTD_PUBLIC_ID_12 = "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"; public static final String TAGLIB_DTD_RESOURCE_PATH_12 = "/javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd"; /** * Public Id and the Resource path (of the cached copy) * of the DTDs for web application deployment descriptors */ public static final String WEBAPP_DTD_PUBLIC_ID_22 = "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"; public static final String WEBAPP_DTD_RESOURCE_PATH_22 = "/javax/servlet/resources/web-app_2_2.dtd"; public static final String WEBAPP_DTD_PUBLIC_ID_23 = "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"; public static final String WEBAPP_DTD_RESOURCE_PATH_23 = "/javax/servlet/resources/web-app_2_3.dtd"; /** * List of the Public IDs that we cache, and their * associated location. This is used by * an EntityResolver to return the location of the * cached copy of a DTD. */ public static final String[] CACHED_DTD_PUBLIC_IDS = { TAGLIB_DTD_PUBLIC_ID_11, TAGLIB_DTD_PUBLIC_ID_12, WEBAPP_DTD_PUBLIC_ID_22, WEBAPP_DTD_PUBLIC_ID_23, }; public static final String[] CACHED_DTD_RESOURCE_PATHS = { TAGLIB_DTD_RESOURCE_PATH_11, TAGLIB_DTD_RESOURCE_PATH_12, WEBAPP_DTD_RESOURCE_PATH_22, WEBAPP_DTD_RESOURCE_PATH_23, };
private static synchronized void initFactory() { if(fDocumentFactory != null) return; fDocumentFactory = DocumentBuilderFactory.newInstance(); fDocumentFactory.setNamespaceAware(true); fDocumentFactory.setIgnoringElementContentWhitespace(true); fDocumentFactory.setValidating(false); } public static synchronized DocumentBuilder getParser() throws ParserConfigurationException { if(fParsersPool.isEmpty()) { // create a new parser initFactory(); DocumentBuilder builder = fDocumentFactory.newDocumentBuilder(); builder.setEntityResolver(entityResolver); return builder; } else { return (DocumentBuilder)fParsersPool.pop(); } } public static synchronized void releaseParser(DocumentBuilder parser) { if(parser != null) fParsersPool.push(parser); } /** * Parse an xml document as an imput stream. * @param is * @return * @throws XMLException */ public static Document parse(InputStream is) { DocumentBuilder builder = null; try { builder = getParser(); // parse the document Document doc = builder.parse(is); return doc; } catch (Exception e) { } finally { releaseParser(builder); } } /** * Parses an xml document as a string. * @param xml * @return * @throws XMLException */ public static Document parse(String xml) { DocumentBuilder builder = null; try { builder = getParser(); // parse the document try { InputStream is = new ByteArrayInputStream(xml.getBytes()); Document doc = builder.parse(is); return doc; } catch (SAXException e) { } catch (IOException e) { } } catch (ParserConfigurationException e) { } finally { releaseParser(builder); } }
/** * Creates a new and empty document. * @return */ public static Document newDocument() { DocumentBuilder builder = null; try { builder = getParser(); return builder.newDocument(); } catch (ParserConfigurationException e) { throw new RuntimeException(e); } finally { releaseParser(builder); } } /** * Creates a new document with a document root element. * @param name * @return */ public static Element newElement(String name) { DocumentBuilder builder = null; try { builder = getParser(); Document doc = builder.newDocument(); Element el = doc.createElement(name); doc.appendChild(el); return el; } catch (ParserConfigurationException e) { throw new RuntimeException(e); } finally { releaseParser(builder); } } /** * Serialize an element to a string. * @param element * @return * @throws XMLException */ public static String ElementToString(Element element) { return privateElementToString(element, true, true); } public static String ElementToString(Element element, boolean pretty) { return privateElementToString(element, true, pretty); } /** * Serialize a document to a string * @param doc * @return */ public static String DocumentToString(Document doc) { return privateElementToString(doc.getDocumentElement(), false, true); } public static String DocumentToString(Document doc, boolean pretty) { return privateElementToString(doc.getDocumentElement(), false, pretty); } /** * Get the first child element to match a given name. * Look for a child element in the same namespace as the parent. * * @param parent * @param name * @return */ public static Element getChild(Element parent, String name) { Element child = getFirstChild(parent); while(child != null) { String tagName = child.getTagName(); if(tagName != null && tagName.equals(name)) { return child; } if(child.getPrefix() != null && child.getPrefix().equals(parent.getPrefix()) && child.getLocalName() != null && child.getLocalName().equals(name)) { return child; } child = getNext(child); } return child; } /** * Get the first child element to match a given name. * Look for a child element in the same namespace as the parent. * * @param parent * @param name * @return */ public static Element getChild(Element parent, String ns, String name) { Element child = getFirstChild(parent); while(child != null) { if(child.getLocalName().equals(name)) { if(ns == null && child.getNamespaceURI() == null) { return child; } else if(ns != null && ns.equals(child.getNamespaceURI())) { return child; } } child = getNext(child); } return child; } /** * Get the first child element of an element. * @param el * @return */ public static Element getFirstChild(Element el) { if(el == null) { return null; } NodeList lst = el.getChildNodes(); int len = lst.getLength(); for (int i = 0; i < len; i++) { Node n = lst.item(i); if (n instanceof Element) return (Element) n; } return null; } /** * Get the next sibling element of a given element. * @param el * @return */ public static Element getNext(Element el) { Node n = el.getNextSibling(); while (n != null && !(n instanceof Element)) { // get the next one n = n.getNextSibling(); } if (n instanceof Element) { return (Element) n; } // else, nothing to return return null; } /** * Get the next sibling element of a given element. * @param el * @return */ public static Element getNextSibling(Element el) { String tagName = el.getTagName(); if(tagName == null) { return null; } Node n = el.getNextSibling(); while (n != null && ( !(n instanceof Element) || !tagName.equals(((Element)n).getTagName()))) { // get the next one n = n.getNextSibling(); } if (n instanceof Element) { return (Element) n; } else { // else, nothing to return return null; } } /** * Get the previous sibling element of a given element. * @param el * @return */ public static Element getPrevious(Element el) { Node n = el.getPreviousSibling(); while (n != null && !(n instanceof Element)) { // get the next one n = n.getPreviousSibling(); } if (n instanceof Element) { return (Element) n; } else { // else, nothing to return return null; } } /** * Get the previous sibling element of a given element. * @param el * @return */ public static Element getPreviousSibling(Element el) { Node n = el.getPreviousSibling(); while (n != null && ( !(n instanceof Element) || !el.getTagName().equals(((Element)n).getTagName()))) { // get the next one n = n.getPreviousSibling(); } if (n instanceof Element) { return (Element) n; } else { // else, nothing to return return null; } } /** * Returns the text value of an element. * @param el * @return */ public static String getTextValue(Element el) { StringBuffer b = new StringBuffer(); // retrieve the text node child NodeList nl = el.getChildNodes(); int len = nl.getLength(); for (int i = 0; i < len; i++) { Node n = nl.item(i); if (n instanceof Text) { Text t = (Text) n; b.append(t.getData()); } } // trim the result, ignoring the first spaces and cariage return int iFirst =0; for(; iFirst<b.length(); iFirst++) { char c = b.charAt(iFirst); if(c != " " && c != "\r" && c != "\n" && c != "\t") { break; } } // start by the end as well int iLast = b.length()-1; for(; iLast>=0; iLast--) { char c = b.charAt(iLast); if(c != " " && c != "\r" && c != "\n" && c != "\t") { break; } } return b.substring(iFirst, iLast+1); } /** * Get the text value of a child element with a given name. * @param parent * @param name * @return */ public static String getChildText(Element parent, String name) { Element child = getChild(parent, name); if (child != null) { return getTextValue(child); } return null; } /** * Get the text value of a child element with a given name. * @param parent * @param name * @return */ public static String getChildText(Element parent, String ns, String name) { Element child = getChild(parent, ns, name); if (child != null) { return getTextValue(child); } return null; } /** * Adds an element as a child of a given element. * The child is created with the same namespace as the parent. * @param parent * @param name * @return */ public static Element addElement(Element parent, String name) { Document doc = parent.getOwnerDocument(); String qname; if(parent.getPrefix() != null) { qname = parent.getPrefix() + ":" + name; } else { qname = name; } Element child = doc.createElementNS(parent.getNamespaceURI(), qname); parent.appendChild(child); return child; } /** * Adds an element as a child of a given element and sets the text value. * The child is created with the same namespace as the parent. * * @param parent * @param name * @param textValue * @return */ public static Element addElement( Element parent, String name, String textValue) { Element child = addElement(parent, name); // create a text node if(textValue == null) { textValue = ""; } Text txt = child.getOwnerDocument().createTextNode(textValue); child.appendChild(txt); return child; } /** * Sets the text value for a given element. * @param el * @param value */ public static void setText(Element el, String value) { // remove the children if already exist while (el.getFirstChild() != null) { el.removeChild(el.getFirstChild()); } if(value == null) { value = ""; } Text txt = el.getOwnerDocument().createTextNode(value); el.appendChild(txt); } /** * Sets the text value for a given element as a CDATA section * @param el * @param value */ public static void setCDATA(Element el, String value) { // remove the children if already exist while (el.getFirstChild() != null) { el.removeChild(el.getFirstChild()); } if(value == null) { value = ""; } CDATASection txt = el.getOwnerDocument().createCDATASection(value); el.appendChild(txt); } /** * Retrieve the namespace for a given prefix. * Does a lookup into the parent hierarchy. * @param el * @param prefix * @return */ public static String getNamespace(Element el, String prefix) { Element parent = el; while (parent != null) { String ns = parent.getAttribute("xmlns:" + prefix); if (ns != null && ns.length() > 0) { return ns; } // get the parent Node n = parent.getParentNode(); if (n instanceof Element) { parent = (Element) n; } else { parent = null; } } // nothing found return null; } /* * serialize an element to a string. */ private static String privateElementToString( Element element, boolean omitXMLDecl, boolean pretty) { try { Source source = new DOMSource(element); StringWriter out = new StringWriter(); StreamResult result = new StreamResult(out); Transformer xformer = TransformerFactory.newInstance().newTransformer(); xformer.setOutputProperty("indent", "yes"); xformer.transform(source, result); return out.toString(); } catch(Exception e) { } } public static String getAttribute(Element el, String att) { String str = el.getAttribute(att); if(str == null || str.length() == 0) { return null; } else { return str; } } static EntityResolver entityResolver = new MyEntityResolver(); static private class MyEntityResolver implements EntityResolver {
public InputSource resolveEntity(String publicId, String systemId) throws SAXException { for (int i = 0; i < CACHED_DTD_PUBLIC_IDS.length; i++) { String cachedDtdPublicId = CACHED_DTD_PUBLIC_IDS[i]; if (cachedDtdPublicId.equals(publicId)) { String resourcePath = CACHED_DTD_RESOURCE_PATHS[i]; InputStream input = this.getClass().getResourceAsStream( resourcePath); if (input == null) { throw new SAXException("file.not.found"+resourcePath); } InputSource isrc = new InputSource(input); return isrc; } } return null; } }
}
</source>
Print Tree node
<source lang="java">
import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletResponse; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /*
* Copyright 2005 Joe Walker * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
/**
* * @author Abey Mullassery * */
public class Main {
public static void printTree(Node doc) { if (doc == null) { System.out.println("Nothing to print!!"); return; } try { System.out.println(doc.getNodeName() + " " + doc.getNodeValue()); NamedNodeMap cl = doc.getAttributes(); for (int i = 0; i < cl.getLength(); i++) { Node node = cl.item(i); System.out.println( "\t" + node.getNodeName() + " ->" + node.getNodeValue()); } NodeList nl = doc.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); printTree(node); } } catch (Throwable e) { System.out.println("Cannot print!! " + e.getMessage()); } }
}
</source>
Reading a DOM tree from XML document
<source lang="java">
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; public class Main {
public static void main(String[] argv) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder loader = factory.newDocumentBuilder(); Document document = loader.parse("sample.xml"); Element tree = document.getDocumentElement(); }
}
</source>
Returns an iterator over the children of the given element with the given tag name
<source lang="java">
import java.util.ArrayList; import java.util.Iterator; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /**
* A utility class to cover up the rough bits of xml parsing * * @author * @version $Revision: 2787 $ */
@SuppressWarnings("unchecked") public class XmlHelper {
/** * Returns an iterator over the children of the given element with the given * tag name. * * @param element * The parent element * @param tagName * The name of the desired child * @return An interator of children or null if element is null. */ public static Iterator getChildrenByTagName(Element element, String tagName) { if (element == null) return null; // getElementsByTagName gives the corresponding elements in the whole // descendance. We want only children NodeList children = element.getChildNodes(); ArrayList goodChildren = new ArrayList(); for (int i = 0; i < children.getLength(); i++) { Node currentChild = children.item(i); if (currentChild.getNodeType() == Node.ELEMENT_NODE && ((Element) currentChild).getTagName().equals(tagName)) { goodChildren.add(currentChild); } } return goodChildren.iterator(); } /** * Gets the child of the specified element having the specified unique name. * If there are more than one children elements with the same name and * exception is thrown. * * @param element * The parent element * @param tagName * The name of the desired child * @return The named child. * * @throws Exception * Child was not found or was not unique. */ public static Element getUniqueChild(Element element, String tagName) throws Exception { Iterator goodChildren = getChildrenByTagName(element, tagName); if (goodChildren != null && goodChildren.hasNext()) { Element child = (Element) goodChildren.next(); if (goodChildren.hasNext()) { throw new Exception("expected only one " + tagName + " tag"); } return child; } else { throw new Exception("expected one " + tagName + " tag"); } } /** * Gets the child of the specified element having the specified name. If the * child with this name doesn"t exist then null is returned instead. * * @param element * the parent element * @param tagName * the name of the desired child * @return either the named child or null * @throws Exception */ public static Element getOptionalChild(Element element, String tagName) throws Exception { return getOptionalChild(element, tagName, null); } /** * Gets the child of the specified element having the specified name. If the * child with this name doesn"t exist then the supplied default element is * returned instead. * * @param element * the parent element * @param tagName * the name of the desired child * @param defaultElement * the element to return if the child doesn"t exist * @return either the named child or the supplied default * @throws Exception */ public static Element getOptionalChild(Element element, String tagName, Element defaultElement) throws Exception { Iterator goodChildren = getChildrenByTagName(element, tagName); if (goodChildren != null && goodChildren.hasNext()) { Element child = (Element) goodChildren.next(); if (goodChildren.hasNext()) { throw new Exception("expected only one " + tagName + " tag"); } return child; } else { return defaultElement; } } /** * Get the content of the given element. * * @param element * The element to get the content for. * @return The content of the element or null. * @throws Exception */ public static String getElementContent(final Element element) throws Exception { return getElementContent(element, null); } /** * Get the content of the given element. * * @param element * The element to get the content for. * @param defaultStr * The default to return when there is no content. * @return The content of the element or the default. * @throws Exception */ public static String getElementContent(Element element, String defaultStr) throws Exception { if (element == null) return defaultStr; NodeList children = element.getChildNodes(); String result = ""; for (int i = 0; i < children.getLength(); i++) { if (children.item(i).getNodeType() == Node.TEXT_NODE || children.item(i).getNodeType() == Node.CDATA_SECTION_NODE) { result += children.item(i).getNodeValue(); } else if (children.item(i).getNodeType() == Node.ruMENT_NODE) { // Ignore comment nodes } } return result.trim(); } /** * Macro to get the content of a unique child element. * * @param element * The parent element. * @param tagName * The name of the desired child. * @return The element content or null. * @throws Exception */ public static String getUniqueChildContent(Element element, String tagName) throws Exception { return getElementContent(getUniqueChild(element, tagName)); } /** * Macro to get the content of an optional child element. * * @param element * The parent element. * @param tagName * The name of the desired child. * @return The element content or null. * @throws Exception */ public static String getOptionalChildContent(Element element, String tagName) throws Exception { return getElementContent(getOptionalChild(element, tagName)); } public static boolean getOptionalChildBooleanContent(Element element, String name) throws Exception { Element child = getOptionalChild(element, name); if (child != null) { String value = getElementContent(child).toLowerCase(); return value.equals("true") || value.equals("yes"); } return false; }
}
</source>
Returns the concatenated child text of the specified node.
<source lang="java">
import org.w3c.dom.Element; import org.w3c.dom.Node; /*
* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
public class Main {
/** * Returns the concatenated child text of the specified node. * This method only looks at the immediate children of type * Node.TEXT_NODE or the children of any child * node that is of type Node.CDATA_SECTION_NODE * for the concatenation. * * @param node The node to look at. */ public static String getChildText(Node node) { // is there anything to do? if (node == null) { return null; } // concatenate children text StringBuffer str = new StringBuffer(); Node child = node.getFirstChild(); while (child != null) { short type = child.getNodeType(); if (type == Node.TEXT_NODE) { str.append(child.getNodeValue()); } else if (type == Node.CDATA_SECTION_NODE) { str.append(getChildText(child)); } child = child.getNextSibling(); } // return text value return str.toString(); } // getChildText(Node):String
}
</source>
Return the next sibling with a given name and type
<source lang="java">
import org.w3c.dom.Node; public class Main {
/** */ public static Node getNext( Node current, String name, int type) { Node first=current.getNextSibling(); if( first==null ) return null; for (Node node = first; node != null; node = node.getNextSibling()) { if( type >= 0 && node.getNodeType() != type ) continue; //System.out.println("getNode: " + name + " " + node.getNodeName()); if( name==null ) return node; if( name.equals( node.getNodeName() ) ) { return node; } } return null; }
}
</source>
Saving a DOM tree to XML file javax.xml.parsers (JAXP)
<source lang="java">
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.sun.org.apache.xml.internal.serialize.XMLSerializer; public class Main {
public static void main(String[] argv) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder loader = factory.newDocumentBuilder(); Document document = loader.newDocument(); Element order = document.createElement("order"); document.appendChild(order); XMLSerializer serializer = new XMLSerializer(); serializer.setOutputCharStream(new java.io.FileWriter("order.xml")); serializer.serialize(document); }
}
</source>
Search earlier siblings for a given node
<source lang="java">
/**********************************************************************************
- Copyright (c) 2003, 2004 The Regents of the University of Michigan, Trustees of Indiana University,
- Board of Trustees of the Leland Stanford, Jr., University, and The MIT Corporation
- Licensed under the Educational Community License Version 1.0 (the "License");
- By obtaining, using and/or copying this Original Work, you agree that you have read,
- understand, and will comply with the terms and conditions of the Educational Community License.
- You may obtain a copy of the License at:
- http://cvs.sakaiproject.org/licenses/license_1_0.html
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- /
import org.w3c.dom.Node; public class Utils {
/** * Search earlier siblings for a given node * @param currentNode Starting point for our search * @param tagName Node name to look up * @return matching Node (null if none) */ public static Node getPreviousSiblingByName(Node currentNode, String tagName) { Node node = currentNode.getPreviousSibling(); while ((node != null) && (!node.getNodeName().equals(tagName))) { node = node.getPreviousSibling(); } return node; }
}
</source>
Search for a named child of a given node
<source lang="java">
import org.w3c.dom.Node; public class Utils {
/** * Search for a named child of a given node * @param currentNode Starting point for our search * @param tagName Node name to look up * @return matching Node (null if none) */ public static Node getChildSiblingByName(Node currentNode, String tagName) { Node node = currentNode.getFirstChild(); while ((node != null) && (!node.getNodeName().equals(tagName))) { node = node.getNextSibling(); } return node; }
}
</source>
Search our next siblings for a given node
<source lang="java">
/**********************************************************************************
- Copyright (c) 2003, 2004 The Regents of the University of Michigan, Trustees of Indiana University,
- Board of Trustees of the Leland Stanford, Jr., University, and The MIT Corporation
- Licensed under the Educational Community License Version 1.0 (the "License");
- By obtaining, using and/or copying this Original Work, you agree that you have read,
- understand, and will comply with the terms and conditions of the Educational Community License.
- You may obtain a copy of the License at:
- http://cvs.sakaiproject.org/licenses/license_1_0.html
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- /
import org.w3c.dom.Node; public class Utils {
/** * Search our next siblings for a given node * @param currentNode Starting point for our search * @param tagName Node name to look up * @return matching Node (null if none) */ public static Node getNextSiblingByName(Node currentNode, String tagName) { Node node = currentNode.getNextSibling(); while ((node != null) && (!node.getNodeName().equals(tagName))) { node = node.getNextSibling(); } return node; }
}
</source>
Search up the tree for a given node
<source lang="java">
/**********************************************************************************
- Copyright (c) 2003, 2004 The Regents of the University of Michigan, Trustees of Indiana University,
- Board of Trustees of the Leland Stanford, Jr., University, and The MIT Corporation
- Licensed under the Educational Community License Version 1.0 (the "License");
- By obtaining, using and/or copying this Original Work, you agree that you have read,
- understand, and will comply with the terms and conditions of the Educational Community License.
- You may obtain a copy of the License at:
- http://cvs.sakaiproject.org/licenses/license_1_0.html
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
- INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- /
import org.w3c.dom.Node; public class Utils {
/** * Search up the tree for a given node * @param currentNode Starting point for our search * @param tagName Node name to look up * @return matching Node (null if none) */ public static Node getPreviousNodeByName(Node currentNode, String tagName) { Node node = currentNode.getParentNode(); while ((node != null) && (!node.getNodeName().equals(tagName))) { node = node.getParentNode(); } return node; }
}
</source>
Traverse a DOM tree in order to get information about the document.
<source lang="java">
/*
* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
import java.io.PrintWriter; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.Text; import org.xml.sax.SAXException; import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXNotSupportedException; import org.xml.sax.SAXParseException; /**
* A sample DOM counter. This sample program illustrates how to * traverse a DOM tree in order to get information about the document. * The output of this program shows the time and count of elements, * attributes, ignorable whitespaces, and characters appearing in * the document. Three times are shown: the parse time, the first * traversal of the document, and the second traversal of the tree.*
* This class is useful as a "poor-man"s" performance tester to
* compare the speed and accuracy of various DOM parsers. However,
* it is important to note that the first parse time of a parser
* will include both VM class load time and parser initialization
* that would not be present in subsequent parses with the same
* file.
* <p>
* Note: The results produced by this program
* should never be accepted as true performance measurements.
*
* @author Andy Clark, IBM
*
* @version $Id: Counter.java 447683 2006-09-19 02:36:31Z mrglavas $
*/
public class Counter {
//
// Constants
//
// feature ids
/** Namespaces feature id (http://xml.org/sax/features/namespaces). */
protected static final String NAMESPACES_FEATURE_ID = "http://xml.org/sax/features/namespaces";
/** Validation feature id (http://xml.org/sax/features/validation). */
protected static final String VALIDATION_FEATURE_ID = "http://xml.org/sax/features/validation";
/** Schema validation feature id (http://apache.org/xml/features/validation/schema). */
protected static final String SCHEMA_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/schema";
/** Schema full checking feature id (http://apache.org/xml/features/validation/schema-full-checking). */
protected static final String SCHEMA_FULL_CHECKING_FEATURE_ID = "http://apache.org/xml/features/validation/schema-full-checking";
/** Honour all schema locations feature id (http://apache.org/xml/features/honour-all-schemaLocations). */
protected static final String HONOUR_ALL_SCHEMA_LOCATIONS_ID = "http://apache.org/xml/features/honour-all-schemaLocations";
/** Validate schema annotations feature id (http://apache.org/xml/features/validate-annotations). */
protected static final String VALIDATE_ANNOTATIONS_ID = "http://apache.org/xml/features/validate-annotations";
/** Dynamic validation feature id (http://apache.org/xml/features/validation/dynamic). */
protected static final String DYNAMIC_VALIDATION_FEATURE_ID = "http://apache.org/xml/features/validation/dynamic";
/** XInclude feature id (http://apache.org/xml/features/xinclude). */
protected static final String XINCLUDE_FEATURE_ID = "http://apache.org/xml/features/xinclude";
/** XInclude fixup base URIs feature id (http://apache.org/xml/features/xinclude/fixup-base-uris). */
protected static final String XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID = "http://apache.org/xml/features/xinclude/fixup-base-uris";
/** XInclude fixup language feature id (http://apache.org/xml/features/xinclude/fixup-language). */
protected static final String XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID = "http://apache.org/xml/features/xinclude/fixup-language";
// default settings
/** Default parser name (dom.wrappers.Xerces). */
protected static final String DEFAULT_PARSER_NAME = "dom.wrappers.Xerces";
/** Default repetition (1). */
protected static final int DEFAULT_REPETITION = 1;
/** Default namespaces support (true). */
protected static final boolean DEFAULT_NAMESPACES = true;
/** Default validation support (false). */
protected static final boolean DEFAULT_VALIDATION = false;
/** Default Schema validation support (false). */
protected static final boolean DEFAULT_SCHEMA_VALIDATION = false;
/** Default Schema full checking support (false). */
protected static final boolean DEFAULT_SCHEMA_FULL_CHECKING = false;
/** Default honour all schema locations (false). */
protected static final boolean DEFAULT_HONOUR_ALL_SCHEMA_LOCATIONS = false;
/** Default validate schema annotations (false). */
protected static final boolean DEFAULT_VALIDATE_ANNOTATIONS = false;
/** Default dynamic validation support (false). */
protected static final boolean DEFAULT_DYNAMIC_VALIDATION = false;
/** Default XInclude processing support (false). */
protected static final boolean DEFAULT_XINCLUDE = false;
/** Default XInclude fixup base URIs support (true). */
protected static final boolean DEFAULT_XINCLUDE_FIXUP_BASE_URIS = true;
/** Default XInclude fixup language support (true). */
protected static final boolean DEFAULT_XINCLUDE_FIXUP_LANGUAGE = true;
//
// Data
//
/** Number of elements. */
protected long fElements;
/** Number of attributes. */
protected long fAttributes;
/** Number of characters. */
protected long fCharacters;
/** Number of ignorable whitespace characters. */
protected long fIgnorableWhitespace;
/** Document information. */
protected ParserWrapper.DocumentInfo fDocumentInfo;
//
// Public methods
//
/** Sets the parser wrapper. */
public void setDocumentInfo(ParserWrapper.DocumentInfo documentInfo) {
fDocumentInfo = documentInfo;
} // setDocumentInfo(ParserWrapper.DocumentInfo)
/** Traverses the specified node, recursively. */
public void count(Node node) {
// is there anything to do?
if (node == null) {
return;
}
int type = node.getNodeType();
switch (type) {
case Node.DOCUMENT_NODE: {
fElements = 0;
fAttributes = 0;
fCharacters = 0;
fIgnorableWhitespace = 0;
Document document = (Document)node;
count(document.getDocumentElement());
break;
}
case Node.ELEMENT_NODE: {
fElements++;
NamedNodeMap attrs = node.getAttributes();
if (attrs != null) {
fAttributes += attrs.getLength();
}
// drop through to entity reference
}
case Node.ENTITY_REFERENCE_NODE: {
Node child = node.getFirstChild();
while (child != null) {
count(child);
child = child.getNextSibling();
}
break;
}
case Node.CDATA_SECTION_NODE: {
fCharacters += ((Text)node).getLength();
break;
}
case Node.TEXT_NODE: {
if (fDocumentInfo != null) {
Text text = (Text)node;
int length = text.getLength();
if (fDocumentInfo.isIgnorableWhitespace(text)) {
fIgnorableWhitespace += length;
}
else {
fCharacters += length;
}
}
break;
}
}
} // count(Node)
/** Prints the results. */
public void printResults(PrintWriter out, String uri,
long parse, long traverse1, long traverse2,
int repetition) {
// filename.xml: 631/200/100 ms (4 elems, 0 attrs, 78 spaces, 0 chars)
out.print(uri);
out.print(": ");
if (repetition == 1) {
out.print(parse);
}
else {
out.print(parse);
out.print("/");
out.print(repetition);
out.print("=");
out.print(parse/repetition);
}
out.print(";");
out.print(traverse1);
out.print(";");
out.print(traverse2);
out.print(" ms (");
out.print(fElements);
out.print(" elems, ");
out.print(fAttributes);
out.print(" attrs, ");
out.print(fIgnorableWhitespace);
out.print(" spaces, ");
out.print(fCharacters);
out.print(" chars)");
out.println();
out.flush();
} // printResults(PrintWriter,String,long,long,long)
//
// MAIN
//
/** Main program entry point. */
public static void main(String argv[]) {
// is there anything to do?
if (argv.length == 0) {
printUsage();
System.exit(1);
}
// variables
Counter counter = new Counter();
PrintWriter out = new PrintWriter(System.out);
ParserWrapper parser = null;
int repetition = DEFAULT_REPETITION;
boolean namespaces = DEFAULT_NAMESPACES;
boolean validation = DEFAULT_VALIDATION;
boolean schemaValidation = DEFAULT_SCHEMA_VALIDATION;
boolean schemaFullChecking = DEFAULT_SCHEMA_FULL_CHECKING;
boolean honourAllSchemaLocations = DEFAULT_HONOUR_ALL_SCHEMA_LOCATIONS;
boolean validateAnnotations = DEFAULT_VALIDATE_ANNOTATIONS;
boolean dynamicValidation = DEFAULT_DYNAMIC_VALIDATION;
boolean xincludeProcessing = DEFAULT_XINCLUDE;
boolean xincludeFixupBaseURIs = DEFAULT_XINCLUDE_FIXUP_BASE_URIS;
boolean xincludeFixupLanguage = DEFAULT_XINCLUDE_FIXUP_LANGUAGE;
// process arguments
for (int i = 0; i < argv.length; i++) {
String arg = argv[i];
if (arg.startsWith("-")) {
String option = arg.substring(1);
if (option.equals("p")) {
// get parser name
if (++i == argv.length) {
System.err.println("error: Missing argument to -p option.");
}
String parserName = argv[i];
// create parser
try {
parser = (ParserWrapper)Class.forName(parserName).newInstance();
}
catch (Exception e) {
parser = null;
System.err.println("error: Unable to instantiate parser ("+parserName+")");
}
continue;
}
if (option.equals("x")) {
if (++i == argv.length) {
System.err.println("error: Missing argument to -x option.");
continue;
}
String number = argv[i];
try {
int value = Integer.parseInt(number);
if (value < 1) {
System.err.println("error: Repetition must be at least 1.");
continue;
}
repetition = value;
}
catch (NumberFormatException e) {
System.err.println("error: invalid number ("+number+").");
}
continue;
}
if (option.equalsIgnoreCase("n")) {
namespaces = option.equals("n");
continue;
}
if (option.equalsIgnoreCase("v")) {
validation = option.equals("v");
continue;
}
if (option.equalsIgnoreCase("s")) {
schemaValidation = option.equals("s");
continue;
}
if (option.equalsIgnoreCase("f")) {
schemaFullChecking = option.equals("f");
continue;
}
if (option.equalsIgnoreCase("hs")) {
honourAllSchemaLocations = option.equals("hs");
continue;
}
if (option.equalsIgnoreCase("va")) {
validateAnnotations = option.equals("va");
continue;
}
if (option.equalsIgnoreCase("dv")) {
dynamicValidation = option.equals("dv");
continue;
}
if (option.equalsIgnoreCase("xi")) {
xincludeProcessing = option.equals("xi");
continue;
}
if (option.equalsIgnoreCase("xb")) {
xincludeFixupBaseURIs = option.equals("xb");
continue;
}
if (option.equalsIgnoreCase("xl")) {
xincludeFixupLanguage = option.equals("xl");
continue;
}
if (option.equals("h")) {
printUsage();
continue;
}
}
// use default parser?
if (parser == null) {
// create parser
try {
parser = (ParserWrapper)Class.forName(DEFAULT_PARSER_NAME).newInstance();
}
catch (Exception e) {
System.err.println("error: Unable to instantiate parser ("+DEFAULT_PARSER_NAME+")");
continue;
}
}
// set parser features
try {
parser.setFeature(NAMESPACES_FEATURE_ID, namespaces);
}
catch (SAXException e) {
System.err.println("warning: Parser does not support feature ("+NAMESPACES_FEATURE_ID+")");
}
try {
parser.setFeature(VALIDATION_FEATURE_ID, validation);
}
catch (SAXException e) {
System.err.println("warning: Parser does not support feature ("+VALIDATION_FEATURE_ID+")");
}
try {
parser.setFeature(SCHEMA_VALIDATION_FEATURE_ID, schemaValidation);
}
catch (SAXException e) {
System.err.println("warning: Parser does not support feature ("+SCHEMA_VALIDATION_FEATURE_ID+")");
}
try {
parser.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, schemaFullChecking);
}
catch (SAXException e) {
System.err.println("warning: Parser does not support feature ("+SCHEMA_FULL_CHECKING_FEATURE_ID+")");
}
try {
parser.setFeature(HONOUR_ALL_SCHEMA_LOCATIONS_ID, honourAllSchemaLocations);
}
catch (SAXException e) {
System.err.println("warning: Parser does not support feature ("+HONOUR_ALL_SCHEMA_LOCATIONS_ID+")");
}
try {
parser.setFeature(VALIDATE_ANNOTATIONS_ID, validateAnnotations);
}
catch (SAXException e) {
System.err.println("warning: Parser does not support feature ("+VALIDATE_ANNOTATIONS_ID+")");
}
try {
parser.setFeature(DYNAMIC_VALIDATION_FEATURE_ID, dynamicValidation);
}
catch (SAXException e) {
System.err.println("warning: Parser does not support feature ("+DYNAMIC_VALIDATION_FEATURE_ID+")");
}
try {
parser.setFeature(XINCLUDE_FEATURE_ID, xincludeProcessing);
}
catch (SAXException e) {
System.err.println("warning: Parser does not support feature ("+XINCLUDE_FEATURE_ID+")");
}
try {
parser.setFeature(XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID, xincludeFixupBaseURIs);
}
catch (SAXException e) {
System.err.println("warning: Parser does not support feature ("+XINCLUDE_FIXUP_BASE_URIS_FEATURE_ID+")");
}
try {
parser.setFeature(XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID, xincludeFixupLanguage);
}
catch (SAXException e) {
System.err.println("warning: Parser does not support feature ("+XINCLUDE_FIXUP_LANGUAGE_FEATURE_ID+")");
}
// parse file
try {
long beforeParse = System.currentTimeMillis();
Document document = null;
for (int j = 0; j < repetition; j++) {
document = parser.parse(arg);
}
long afterParse = System.currentTimeMillis();
long parse = afterParse - beforeParse;
ParserWrapper.DocumentInfo documentInfo = parser.getDocumentInfo();
counter.setDocumentInfo(documentInfo);
long beforeTraverse1 = System.currentTimeMillis();
counter.count(document);
long afterTraverse1 = System.currentTimeMillis();
long traverse1 = afterTraverse1 - beforeTraverse1;
long beforeTraverse2 = System.currentTimeMillis();
counter.count(document);
long afterTraverse2 = System.currentTimeMillis();
long traverse2 = afterTraverse2 - beforeTraverse2;
counter.printResults(out, arg, parse, traverse1, traverse2,
repetition);
}
catch (SAXParseException e) {
// ignore
}
catch (Exception e) {
System.err.println("error: Parse error occurred - "+e.getMessage());
Exception se = e;
if (e instanceof SAXException) {
se = ((SAXException)e).getException();
}
if (se != null)
se.printStackTrace(System.err);
else
e.printStackTrace(System.err);
}
}
} // main(String[])
//
// Private static methods
//
/** Prints the usage. */
private static void printUsage() {
System.err.println("usage: java dom.Counter (options) uri ...");
System.err.println();
System.err.println("options:");
System.err.println(" -p name Select parser by name.");
System.err.println(" -x number Select number of repetitions.");
System.err.println(" -n | -N Turn on/off namespace processing.");
System.err.println(" -v | -V Turn on/off validation.");
System.err.println(" -s | -S Turn on/off Schema validation support.");
System.err.println(" NOTE: Not supported by all parsers.");
System.err.println(" -f | -F Turn on/off Schema full checking.");
System.err.println(" NOTE: Requires use of -s and not supported by all parsers.");
System.err.println(" -hs | -HS Turn on/off honouring of all schema locations.");
System.err.println(" NOTE: Requires use of -s and not supported by all parsers.");
System.err.println(" -va | -VA Turn on/off validation of schema annotations.");
System.err.println(" NOTE: Requires use of -s and not supported by all parsers.");
System.err.println(" -dv | -DV Turn on/off dynamic validation.");
System.err.println(" NOTE: Not supported by all parsers.");
System.err.println(" -xi | -XI Turn on/off XInclude processing.");
System.err.println(" NOTE: Not supported by all parsers.");
System.err.println(" -xb | -XB Turn on/off base URI fixup during XInclude processing.");
System.err.println(" NOTE: Requires use of -xi and not supported by all parsers.");
System.err.println(" -xl | -XL Turn on/off language fixup during XInclude processing.");
System.err.println(" NOTE: Requires use of -xi and not supported by all parsers.");
System.err.println(" -h This help screen.");
System.err.println();
System.err.println("defaults:");
System.err.println(" Parser: "+DEFAULT_PARSER_NAME);
System.err.println(" Repetition: "+DEFAULT_REPETITION);
System.err.print(" Namespaces: ");
System.err.println(DEFAULT_NAMESPACES ? "on" : "off");
System.err.print(" Validation: ");
System.err.println(DEFAULT_VALIDATION ? "on" : "off");
System.err.print(" Schema: ");
System.err.println(DEFAULT_SCHEMA_VALIDATION ? "on" : "off");
System.err.print(" Schema full checking: ");
System.err.println(DEFAULT_SCHEMA_FULL_CHECKING ? "on" : "off");
System.err.print(" Honour all schema locations: ");
System.err.println(DEFAULT_HONOUR_ALL_SCHEMA_LOCATIONS ? "on" : "off");
System.err.print(" Validate annotations: ");
System.err.println(DEFAULT_VALIDATE_ANNOTATIONS ? "on" : "off");
System.err.print(" Dynamic: ");
System.err.println(DEFAULT_DYNAMIC_VALIDATION ? "on" : "off");
System.err.print(" XInclude: ");
System.err.println(DEFAULT_XINCLUDE ? "on" : "off");
System.err.print(" XInclude base URI fixup: ");
System.err.println(DEFAULT_XINCLUDE_FIXUP_BASE_URIS ? "on" : "off");
System.err.print(" XInclude language fixup: ");
System.err.println(DEFAULT_XINCLUDE_FIXUP_LANGUAGE ? "on" : "off");
} // printUsage()
} // class DOMCount
/**
* Encapsulates a DOM parser.
*
* @version $Id: ParserWrapper.java 447683 2006-09-19 02:36:31Z mrglavas $
*/
interface ParserWrapper {
//
// ParserWrapper methods
//
/** Parses the specified URI and returns the document. */
public Document parse(String uri) throws Exception;
/**
* Set the state of a feature.
*
* Set the state of any feature in a SAX2 parser. The parser
* might not recognize the feature, and if it does recognize
* it, it might not be able to fulfill the request.
*
* @param featureId The unique identifier (URI) of the feature.
* @param state The requested state of the feature (true or false).
*
* @exception org.xml.sax.SAXNotRecognizedException If the
* requested feature is not known.
* @exception org.xml.sax.SAXNotSupportedException If the
* requested feature is known, but the requested
* state is not supported.
* @exception org.xml.sax.SAXException If there is any other
* problem fulfilling the request.
*/
public void setFeature(String featureId, boolean state)
throws SAXNotRecognizedException, SAXNotSupportedException;
/** Returns the document information. */
public DocumentInfo getDocumentInfo();
//
// Interfaces
//
/**
* This interface is here to query information about the document
* implementation returned by the ParserWrapper#parse
* method.
*
* @author Andy Clark, IBM
*/
public interface DocumentInfo {
//
// DocumentInfo methods
//
/**
* Returns true if the specified text node is ignorable whitespace.
*/
public boolean isIgnorableWhitespace(Text text);
} // interface DocumentInfo
} // interface ParserWrapper
</source>
Traverse a DOM tree in order to print a document that is parsed.
<source lang="java">
/*
* * * The Apache Software License, Version 1.1 * * Copyright (c) 1999 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS"" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */
import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /**
* Traverse a DOM tree in order to print a document that is parsed. * * @author Andy Clark, IBM * @author Thomas.Diesler@jboss.org */
@SuppressWarnings("unchecked") public class DOMWriter {
// Print writer private PrintWriter out; // True, if canonical output private boolean canonical; // True, if pretty printing should be used private boolean prettyprint; // True, if the XML declaration should be written private boolean writeXMLDeclaration; // True, if whitespace should be ignored private boolean ignoreWhitespace; // Explicit character set encoding private String charsetName; // indent for the pretty printer private int prettyIndent; // True, if the XML declaration has been written private boolean wroteXMLDeclaration; // The node that started the write private Node rootNode; // True if we want namespace completion private boolean completeNamespaces = true; // The current default namespace private String currentDefaultNamespace; public DOMWriter(Writer w) { this.out = new PrintWriter(w); } public DOMWriter(Writer w, String charsetName) { this.out = new PrintWriter(w); this.charsetName = charsetName; this.writeXMLDeclaration = true; } public DOMWriter(OutputStream stream) { try { this.out = new PrintWriter(new OutputStreamWriter(stream, "UTF-8")); } catch (UnsupportedEncodingException e) { // ignore, UTF-8 should be available } } public DOMWriter(OutputStream stream, String charsetName) { try { this.out = new PrintWriter(new OutputStreamWriter(stream, charsetName)); this.charsetName = charsetName; this.writeXMLDeclaration = true; } catch (UnsupportedEncodingException e) { throw new IllegalArgumentException("Unsupported encoding: " + charsetName); } } /** * Print a node with explicit prettyprinting. * The defaults for all other DOMWriter properties apply. * */ public static String printNode(Node node, boolean prettyprint) { StringWriter strw = new StringWriter(); new DOMWriter(strw).setPrettyprint(prettyprint).print(node); return strw.toString(); } public boolean isCanonical() { return canonical; } /** * Set wheter entities should appear in their canonical form. * The default is false. */ public DOMWriter setCanonical(boolean canonical) { this.canonical = canonical; return this; } public boolean isIgnoreWhitespace() { return ignoreWhitespace; } /** * Set whether whitespace should be ignored. * The default is false. */ public DOMWriter setIgnoreWhitespace(boolean ignoreWhitespace) { this.ignoreWhitespace = ignoreWhitespace; return this; } /** * Set wheter subelements should have their namespaces completed. * Setting this to false may lead to invalid XML fragments. * The default is true. */ public DOMWriter setCompleteNamespaces(boolean complete) { this.rupleteNamespaces = complete; return this; } public boolean isPrettyprint() { return prettyprint; } /** * Set wheter element should be indented. * The default is false. */ public DOMWriter setPrettyprint(boolean prettyprint) { this.prettyprint = prettyprint; return this; } public boolean isWriteXMLDeclaration() { return writeXMLDeclaration; } /** * Set wheter the XML declaration should be written. * The default is false. */ public DOMWriter setWriteXMLDeclaration(boolean flag) { this.writeXMLDeclaration = flag; return this; } public void print(Node node) { if (prettyprint && ignoreWhitespace) throw new IllegalStateException("Cannot pretty print and ignore whitespace"); rootNode = node; printInternal(node, false); } private void printInternal(Node node, boolean indentEndMarker) { // is there anything to do? if (node == null) { return; } // JBAS-2117 - Don"t skip the DOCUMENT_NODE // if (node instanceof Document) node = ((Document)node).getDocumentElement(); if (wroteXMLDeclaration == false && writeXMLDeclaration == true && canonical == false) { out.print("<?xml version="1.0""); if (charsetName != null) out.print(" encoding="" + charsetName + """); out.print("?>"); if (prettyprint) out.println(); wroteXMLDeclaration = true; } int type = node.getNodeType(); boolean hasChildNodes = node.getChildNodes().getLength() > 0; String nodeName = node.getNodeName(); switch (type) { // print document case Node.DOCUMENT_NODE: { NodeList children = node.getChildNodes(); for (int iChild = 0; iChild < children.getLength(); iChild++) { printInternal(children.item(iChild), false); } out.flush(); break; } // print element with attributes case Node.ELEMENT_NODE: { Element element = (Element)node; if (prettyprint) { for (int i = 0; i < prettyIndent; i++) { out.print(" "); } prettyIndent++; } out.print("<"); out.print(nodeName); Map nsMap = new HashMap(); String elPrefix = node.getPrefix(); String elNamespaceURI = node.getNamespaceURI(); if (elPrefix != null) { String nsURI = getNamespaceURI(elPrefix, element, rootNode); nsMap.put(elPrefix, nsURI); } Attr attrs[] = sortAttributes(node.getAttributes()); for (int i = 0; i < attrs.length; i++) { Attr attr = attrs[i]; String atPrefix = attr.getPrefix(); String atName = attr.getNodeName(); String atValue = normalize(attr.getNodeValue(), canonical); if (atName.equals("xmlns")) currentDefaultNamespace = atValue; if (atPrefix != null && !atPrefix.equals("xmlns") && !atPrefix.equals("xml")) { String nsURI = getNamespaceURI(atPrefix, element, rootNode); nsMap.put(atPrefix, nsURI); // xsi:type="ns1:SubType", xsi:type="xsd:string" if (atName.equals(atPrefix + ":type") && atValue.indexOf(":") > 0) { // xsi defined on the envelope if (nsURI == null) nsURI = getNamespaceURI(atPrefix, element, null); if ("http://www.w3.org/2001/XMLSchema-instance".equals(nsURI)) { String typePrefix = atValue.substring(0, atValue.indexOf(":")); String typeURI = getNamespaceURI(typePrefix, element, rootNode); nsMap.put(typePrefix, typeURI); } } } out.print(" " + atName + "="" + atValue + """); } // Add namespace declaration for prefixes // that are defined further up the tree if (completeNamespaces) { Iterator itPrefix = nsMap.keySet().iterator(); while (itPrefix.hasNext()) { String prefix = (String)itPrefix.next(); String nsURI = (String)nsMap.get(prefix); if (nsURI == null) { nsURI = getNamespaceURI(prefix, element, null); out.print(" xmlns:" + prefix + "="" + nsURI + """); } } } // The SAX ContentHandler will by default not add the namespace declaration // <Hello xmlns="http://somens">World</Hello> if (elPrefix == null && elNamespaceURI != null) { String defaultNamespace = element.getAttribute("xmlns"); if (defaultNamespace.length() == 0 && !elNamespaceURI.equals(currentDefaultNamespace)) { out.print(" xmlns="" + elNamespaceURI + """); currentDefaultNamespace = elNamespaceURI; } } if (hasChildNodes) { out.print(">"); } // Find out if the end marker is indented indentEndMarker = isEndMarkerIndented(node); if (indentEndMarker) { out.print("\n"); } NodeList childNodes = node.getChildNodes(); int len = childNodes.getLength(); for (int i = 0; i < len; i++) { Node childNode = childNodes.item(i); printInternal(childNode, false); } break; } // handle entity reference nodes case Node.ENTITY_REFERENCE_NODE: { if (canonical) { NodeList children = node.getChildNodes(); if (children != null) { int len = children.getLength(); for (int i = 0; i < len; i++) { printInternal(children.item(i), false); } } } else { out.print("&"); out.print(nodeName); out.print(";"); } break; } // print cdata sections case Node.CDATA_SECTION_NODE: { if (canonical) { out.print(normalize(node.getNodeValue(), canonical)); } else { out.print("<![CDATA["); out.print(node.getNodeValue()); out.print("]]>"); } break; } // print text case Node.TEXT_NODE: { String text = normalize(node.getNodeValue(), canonical); if (text.trim().length() > 0) { out.print(text); } else if (prettyprint == false && ignoreWhitespace == false) { out.print(text); } break; } // print processing instruction case Node.PROCESSING_INSTRUCTION_NODE: { out.print("<?"); out.print(nodeName); String data = node.getNodeValue(); if (data != null && data.length() > 0) { out.print(" "); out.print(data); } out.print("?>"); break; } // print comment case Node.ruMENT_NODE: { for (int i = 0; i < prettyIndent; i++) { out.print(" "); } out.print(""); if (prettyprint) { out.print("\n"); } break; } } if (type == Node.ELEMENT_NODE) { if (prettyprint) prettyIndent--; if (hasChildNodes == false) { out.print("/>"); } else { if (indentEndMarker) { for (int i = 0; i < prettyIndent; i++) { out.print(" "); } } out.print("</"); out.print(nodeName); out.print(">"); } if (prettyIndent > 0) { out.print("\n"); } } out.flush(); } private String getNamespaceURI(String prefix, Element element, Node stopNode) { Node parent = element.getParentNode(); String nsURI = element.getAttribute("xmlns:" + prefix); if (nsURI.length() == 0 && element != stopNode && parent instanceof Element) return getNamespaceURI(prefix, (Element)parent, stopNode); return (nsURI.length() > 0 ? nsURI : null); } private boolean isEndMarkerIndented(Node node) { if (prettyprint) { NodeList childNodes = node.getChildNodes(); int len = childNodes.getLength(); for (int i = 0; i < len; i++) { Node children = childNodes.item(i); if (children.getNodeType() == Node.ELEMENT_NODE) { return true; } } } return false; } /** Returns a sorted list of attributes. */ private Attr[] sortAttributes(NamedNodeMap attrs) { int len = (attrs != null) ? attrs.getLength() : 0; Attr array[] = new Attr[len]; for (int i = 0; i < len; i++) { array[i] = (Attr)attrs.item(i); } for (int i = 0; i < len - 1; i++) { String name = array[i].getNodeName(); int index = i; for (int j = i + 1; j < len; j++) { String curName = array[j].getNodeName(); if (curName.rupareTo(name) < 0) { name = curName; index = j; } } if (index != i) { Attr temp = array[i]; array[i] = array[index]; array[index] = temp; } } return (array); } /** Normalizes the given string. */ public static String normalize(String s, boolean canonical) { StringBuffer str = new StringBuffer(); int len = (s != null) ? s.length() : 0; for (int i = 0; i < len; i++) { char ch = s.charAt(i); switch (ch) { case "<": { str.append("<"); break; } case ">": { str.append(">"); break; } case "&": { str.append("&"); break; } case """: { str.append("""); break; } case "\"": { str.append("'"); break; } case "\r": case "\n": { if (canonical) { str.append("&#"); str.append(Integer.toString(ch)); str.append(";"); break; } // else, default append char } default: { str.append(ch); } } } return (str.toString()); }
}
</source>
Traverse the DOM tree as a list
<source lang="java">
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.traversal.DocumentTraversal; import org.w3c.dom.traversal.NodeFilter; import org.w3c.dom.traversal.NodeIterator; public class Main {
public static void main(String[] argv) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder loader = factory.newDocumentBuilder(); Document document = loader.parse("sample.xml"); DocumentTraversal traversal = (DocumentTraversal) document; NodeIterator iterator = traversal.createNodeIterator(document.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true); for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) { System.out.println("Element: " + ((Element) n).getTagName()); } }
}
</source>
Traverse the DOM tree using TreeWalker
<source lang="java">
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.traversal.DocumentTraversal; import org.w3c.dom.traversal.NodeFilter; import org.w3c.dom.traversal.TreeWalker; public class Main {
public static void main(String[] argv) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder loader = factory.newDocumentBuilder(); Document document = loader.parse("sample.xml"); DocumentTraversal traversal = (DocumentTraversal) document; TreeWalker walker = traversal.createTreeWalker(document.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true); traverseLevel(walker, ""); } private static final void traverseLevel(TreeWalker walker, String indent) { Node parend = walker.getCurrentNode(); System.out.println(indent + "- " + ((Element) parend).getTagName()); for (Node n = walker.firstChild(); n != null; n = walker.nextSibling()) { traverseLevel(walker, indent + "\t"); } walker.setCurrentNode(parend); }
}
</source>
Using ranges in DOM tree
<source lang="java">
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.ranges.DocumentRange; import org.w3c.dom.ranges.Range; public class Main {
public static void main(String[] argv) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder loader = factory.newDocumentBuilder(); Document document = loader.parse("sample.xml"); Element order = document.getDocumentElement(); DocumentRange ranges = (DocumentRange) document; Range range = ranges.createRange(); range.setStartBefore(order.getFirstChild()); range.setEndAfter(order.getLastChild()); range.deleteContents(); range.detach(); }
}
</source>