A utility class which provides methods for working with a W3C DOM : DOM « XML « Java






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

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


import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * A utility class which provides methods for working with a W3C DOM.
 */
public class DomUtil {

    public static final Properties OUTPUT_PROPERTIES_INDENT;
    static {
        OUTPUT_PROPERTIES_INDENT = new Properties();
        OUTPUT_PROPERTIES_INDENT.setProperty(OutputKeys.INDENT, "yes");
        OUTPUT_PROPERTIES_INDENT.setProperty("{http://xml.apache.org/xalan}indent-amount", "4");    
    }
    
    /**
     * Entity resolver which throws a SAXException when invoked to avoid external entity injection.
     */
    private static final EntityResolver entityResolver = new EntityResolver() {
    
        /**
         * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String)
         */
        public InputSource resolveEntity(String publicId, String systemId)
        throws SAXException, IOException {
            throw new SAXException("External entities not supported.");
        }
    };

    /**
     * ThreadLocal cache of <code>DocumentBuilder</code> instances.
     */
    private static final ThreadLocal documentBuilders = new ThreadLocal() {
    
        /**
         * @see java.lang.ThreadLocal#initialValue()
         */
        protected Object initialValue() {
            try {
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                factory.setNamespaceAware(true);
                DocumentBuilder builder = factory.newDocumentBuilder();
                builder.setEntityResolver(entityResolver);
                return builder;
            } catch (ParserConfigurationException ex) {
                throw new RuntimeException(ex);
            }
        }
    };
    
    /**
     * ThreadLocal cache of <code>TransformerFactory</code> instances.
     */
    private static final ThreadLocal transformerFactories = new ThreadLocal() {
    
        /**
         * @see java.lang.ThreadLocal#initialValue()
         */
        protected Object initialValue() {
            TransformerFactory factory = TransformerFactory.newInstance();
            return factory;
        }
    };
    
    /**
     * Creates a new document.
     * 
     * @param qualifiedName the qualified name of the document type to be 
     *        created
     * @param publicId the external subset public identifier
     * @param systemId the external subset system identifier
     * @param namespaceUri the namespace URI of the document element to create
     */
    public static Document createDocument(String qualifiedName, String publicId, String systemId, String namespaceUri) {
        DOMImplementation dom = DomUtil.getDocumentBuilder().getDOMImplementation();
        DocumentType docType = dom.createDocumentType(qualifiedName, publicId, systemId);
        Document document = dom.createDocument(namespaceUri, qualifiedName, docType);
        if (namespaceUri != null) {
            document.getDocumentElement().setAttribute("xmlns", namespaceUri);
        }
        return document;
    }

    /**
     * Retrieves a thread-specific <code>DocumentBuilder</code>.
     * As it is a shared resource, the returned object should not be reconfigured in any fashion.
     * 
     * @return the <code>DocumentBuilder</code> serving the current thread.
     */
    public static DocumentBuilder getDocumentBuilder() {
        return (DocumentBuilder) documentBuilders.get();
    }
    
    /**
     * Retrieves a thread-specific <code>TransformerFactory</code>.
     * As it is a shared resource, the returned object should not be reconfigured in any fashion.
     * 
     * @return the <code>TransformerFactory</code> serving the current thread.
     */
    public static TransformerFactory getTransformerFactory() {
        return (TransformerFactory) transformerFactories.get();
    }
    
    /**
     * Determines whether a specific boolean flag is set on an element.
     * 
     * @param element The element to analyze.
     * @param attributeName The name of the boolean 'flag' attribute.
     * @return True if the value of the attribute is 'true', false if it is
     *         not or if the attribute does not exist.
     */
    public static boolean getBooleanAttribute(Element element, String attributeName) {
        String value = element.getAttribute(attributeName);
        if (value == null) {
            return false;
        } else if (value.equals("true")) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Retrieves the first immediate child element of the specified element  
     * whose name matches the provided <code>name</code> parameter.
     * 
     * @param parentElement The element to search.
     * @param name The name of the child element.
     * @return The child element, or null if none was found. 
     */
    public static Element getChildElementByTagName(Element parentElement, String name) {
        NodeList nodes = parentElement.getChildNodes();
        int length = nodes.getLength();
        for (int index = 0; index < length; ++index) {
            if (nodes.item(index).getNodeType() == Node.ELEMENT_NODE
                    && name.equals(nodes.item(index).getNodeName())) {
                return (Element) nodes.item(index);
            }
        }
        return null;
    }
    
    /**
     * Retrieves all immediate child elements of the specified element whose
     * names match the provided <code>name</code> parameter.
     * 
     * @param parentElement The element to search.
     * @param name The name of the child element.
     * @return An array of matching child elements.
     */
    public static Element[] getChildElementsByTagName(Element parentElement, String name) {
        List children = new ArrayList();
        NodeList nodes = parentElement.getChildNodes();
        int length = nodes.getLength();
        for (int index = 0; index < length; ++index) {
            if (nodes.item(index).getNodeType() == Node.ELEMENT_NODE
                    && name.equals(nodes.item(index).getNodeName())) {
                children.add(nodes.item(index));
            }
        }
        Element[] childElements = new Element[children.size()];
        return (Element[]) children.toArray(childElements);
    }

    /**
     * Counts the number of immediate child elements of the specified element
     * whose names match the provided <code>name</code> parameter.
     * 
     * @param parentElement The element to analyze.
     * @param name The name of the child element.
     * @return The number of matching child elements.
     */
    public static int getChildElementCountByTagName(Element parentElement, String name) {
        NodeList nodes = parentElement.getChildNodes();
        int length = nodes.getLength();
        int count = 0;
        for (int index = 0; index < length; ++index) {
            if (nodes.item(index).getNodeType() == Node.ELEMENT_NODE
                    && name.equals(nodes.item(index).getNodeName())) {
                ++count;
            }
        }
        return count;
    }
    
    /**
     * Returns the text content of a DOM <code>Element</code>.
     * 
     * @param element The <code>Element</code> to analyze.
     */
    public static String getElementText(Element element) {
        NodeList children = element.getChildNodes();
        int childCount = children.getLength();
        for (int index = 0; index < childCount; ++index) {
            if (children.item(index) instanceof Text) {
                Text text = (Text) children.item(index);
                return text.getData();
            }
        }
        return null;
    }
    
    /**
     * Writes the <code>Document</code> to the specified <code>OutputStream</code>.
     * 
     * @param document the <code>Document</code>
     * @param out the <code>OutputStream</code>
     * @param outputProperties output properties passed to XML transformer
     * @throws SAXException
     */
    public static void save(Document document, OutputStream out, Properties outputProperties) 
    throws SAXException {
        saveImpl(document, new StreamResult(out), outputProperties);
    }
    
    /**
     * Writes the <code>Document</code> to the specified <code>PrintWriter</code>.
     * 
     * @param document the <code>Document</code>
     * @param w the <code>PrintWriter</code>
     * @param outputProperties output properties passed to XML transformer
     * @throws SAXException
     */
    public static void save(Document document, PrintWriter w, Properties outputProperties) 
    throws SAXException {
        saveImpl(document, new StreamResult(w), outputProperties);
    }
    
    /**
     * Work method for public save() methods.
     */
    private static void saveImpl(Document document, StreamResult output, Properties outputProperties) 
    throws SAXException {
        try {
            TransformerFactory tFactory = getTransformerFactory();
            Transformer transformer = tFactory.newTransformer();
            if (outputProperties != null) {
                transformer.setOutputProperties(outputProperties);
            }
            DOMSource source = new DOMSource(document);
            
            transformer.transform(source, output);
        } catch (TransformerException ex) {
            throw new SAXException("Unable to write document to OutputStream.", ex);
        }
    }

    /**
     * Sets the text content of a DOM <code>Element</code>.
     * 
     * @param element The <code>Element</code> to modify.
     * @param value The new text value.
     */
    public static void setElementText(Element element, String value) {
        NodeList children = element.getChildNodes();
        int childCount = children.getLength();
        for (int index = 0; index < childCount; ++index) {
            if (children.item(index) instanceof Text) {
                Text text = (Text) children.item(index);
                text.setData(value);
                return;
            }
        }
        Text text = element.getOwnerDocument().createTextNode(value);
        element.appendChild(text);
    }
    
    /** Non-instantiable class. */
    private DomUtil() { }
}

   
    
    
    
    
  








Related examples in the same category

1.Parsing a Document Using JAXP
2.XML Document information by DOM
3.Using DOM for Syntax Checking
4.Using the DOM Parser to Build a Document TreeUsing the DOM Parser to Build a Document Tree
5.DOM FeaturesDOM Features
6.DOM level 2 EventsDOM level 2 Events
7.Searching through a document
8.Check a vendor's DOM implementationCheck a vendor's DOM implementation
9.Make up and write an XML document, using DOMMake up and write an XML document, using DOM
10.Creating XML Document using DOM
11.Loading an XML Document using DOM
12.Parse an XML string: Using DOM and a StringReader.
13.Create an XML document with DOM
14.Extracting an XML formatted string out of a DOM object
15.Reading an XML Document and create user-defined object from DOM
16.Visiting All the Nodes in a DOM Document
17.Generating SAX Parsing Events by Traversing a DOM Document
18.Converting an XML Fragment into a DOM Fragment
19.XML DOM Utilities
20.Convenience methods for working with the DOM API
21.DOM Utils
22.Utilities to read DOM
23.W3C DOM utility methods
24.Read XML as DOM
25.Utility method for parsing the XML with DOM
26.Handles DOM processing allowing the reading and writing of hierarchical structures as XML files.
27.Xml Utils for dom4j
28.DocWriter has a static method for writing XML documents with a writer