XML Utility

package sample;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.Writer;

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.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * XML utility class.
 * 
 * @author $Author: Lihong Gao $
 */
public final class XMLUtil {

    /** Hide default constructor */
    private XMLUtil() {
    }

    /**
     * Selects single node specified by the XPath expression.
     * 
     * @param current
     *            XPath query root node
     * @param xpath
     *            XPath expression
     * @return Selected node
     * @throws AIUException
     *             Indicates more than one nodes are selected
     */
    public static Node selectSingleNode(Node current, String xpath)
            throws Exception {
        // final String method = "selectSingleNode(Node,String)";

        NodeList list = selectNodes(current, xpath);
        if (list == null || list.getLength() == 0) {
            return null;
        } else if (list.getLength() == 1) {
            return list.item(0);
        } else {
            throw new Exception("More than one nodes are selected");
        }
    }

    /**
     * Selects list of nodes specified by the XPath expression.
     * 
     * @param current
     *            XPath query root node
     * @param xpath
     *            XPath expression
     * @return Selected node list
     * @throws AIUException
     *             Indicates XML transform failure
     */
    public static NodeList selectNodes(Node current, String xpath)
            throws Exception {
        // final String method = "selectNodes(Node,String)";

        if (current instanceof Element && xpath.indexOf('/') == -1
                && xpath.indexOf('[') == -1) {
            return ((Element) current).getElementsByTagName(xpath);
        } else {
            String xltString = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                    + "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
                    + "<xsl:output version=\"1.0\" method=\"xml\" encoding=\"utf-8\" />"
                    + "<xsl:template match=\"" + xpath + "\">"
                    + "<xsl:copy-of select=\".\" />" + "</xsl:template>"
                    + "<xsl:template match=\"text()\"/>" + "</xsl:stylesheet>";

            try {
                Element result = (Element) current.cloneNode(false);
                StreamSource template = new StreamSource(new StringReader(
                        xltString));

                TransformerFactory transformerFactory = TransformerFactory
                        .newInstance();
                Transformer transformer = transformerFactory
                        .newTransformer(template);
                transformer.transform(new DOMSource(current), new DOMResult(
                        result));
                return result.getChildNodes();
            } catch (TransformerException ex) {
                throw new Exception(ex.getMessage(), ex);
            }
        }
    }

    /**
     * Retrieves text node values as text recursively.
     * 
     * @param root
     *            Root node
     * @param xpath
     *            XPath expression
     * @return String representation of text nodes
     * @throws Exception
     *             Indicates more than one nodes are selected
     */
    public static String getTextValue(Node root, String xpath) throws Exception {
        StringBuffer buf = new StringBuffer();

        Node node = selectSingleNode(root, xpath);
        if (node == null) {
            return null;
        }

        NodeList children = node.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            if (child.getNodeType() == Node.TEXT_NODE) {
                buf.append(child.getNodeValue());
            }
        }

        return buf.toString();
    }

    /**
     * Removes all elements specified by element name.
     * 
     * @param node
     *            Node to modify
     * @param name
     *            Element name
     */
    public static void removeNode(Node node, String name) {
        NodeList nodes = ((Element) node).getElementsByTagName(name);
        if (nodes != null) {
            for (int i = 0; i < nodes.getLength(); i++) {
                node.removeChild(nodes.item(i));
            }
        }
    }

    /**
     * Exports DOM node tree to specified output stream.
     * 
     * @param root
     *            Root node
     * @param out
     *            Output writer
     * @throws Exception
     *             Indicates failed to export nodes
     */
    public static void exportNodes(Node root, Writer out) throws Exception {
        exportNodes(root, new StreamResult(out));
    }

    /**
     * Exports DOM node tree to specified output stream.
     * 
     * @param root
     *            Root node
     * @param out
     *            Output stream
     * @throws Exception
     *             Indicates failed to export nodes
     */
    public static void exportNodes(Node root, OutputStream out)
            throws Exception {
        exportNodes(root, new StreamResult(out));
    }

    /**
     * Exports DOM node tree to specified output stream.
     * 
     * @param root
     *            Root node
     * @param result
     *            Result
     * @throws Exception
     *             Indicates failed to export nodes
     */
    public static void exportNodes(Node root, StreamResult result)
            throws Exception {
        // final String method = "exportNodes(Node,OutputStream)";
        final String xltString = "<?xml version=\"1.0\" encoding=\"Shift_JIS\"?>"
                + "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
                + "<xsl:output method=\"xml\" version=\"1.0\" encoding=\"Shift_JIS\" omit-xml-declaration=\"yes\" />"
                + "<xsl:template match=\"*\">"
                + "<xsl:copy-of select=\".\" />"
                + "</xsl:template>" + "</xsl:stylesheet>";

        try {
            StreamSource template = new StreamSource(
                    new StringReader(xltString));
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(template);
            transformer.setOutputProperty(OutputKeys.ENCODING, "Shift_JIS");
            transformer.transform(new DOMSource(root), result);
        } catch (TransformerException ex) {
            throw new TransformerException(ex.getMessage(), ex);
        }
    }

    /**
     * Converts Node to Document.
     * 
     * @param node
     *            Node
     * @return Document
     * @throws Exception
     *             Indicates failed to convert.
     */
    public static Document convertToDocument(Node node) throws Exception {
        Document doc = createDocument();
        doc.appendChild(doc.importNode(node, true));
        return doc;
    }

    /**
     * Constructs new Document.
     * 
     * @return Document
     * @throws Exception
     *             Indicates failed to convert.
     */
    public static Document createDocument() throws Exception {
        // final String method = "createDocument()";
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory
                    .newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            return builder.newDocument();
        } catch (DOMException e) {
            throw new DOMException(ISeverityLevels.IMPORTANT, e.getMessage());
        } catch (ParserConfigurationException e) {
            throw new ParserConfigurationException(e.getMessage());
        }
    }

    /**
     * Parses specified XML and returns constructed document.
     * 
     * @param xml
     *            XML to parse
     * @return Document
     * @throws Exception
     *             Indicates failed to convert.
     */
    public static Document parseDocument(String xml) throws Exception {
        // final String method = "parseDocument(String)";
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory
                    .newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            return builder.parse(new InputSource(new StringReader(xml)));
        } catch (IOException e) {
            throw new IOException(e.getMessage(), e);
        } catch (DOMException e) {
            throw new DOMException(ISeverityLevels.IMPORTANT, e.getMessage());
        } catch (ParserConfigurationException e) {
            throw new ParserConfigurationException(e.getMessage());
        } catch (SAXException e) {
            throw new SAXException(e.getMessage(), e);
        }
    }

    public interface ISeverityLevels {
        // severity levels for Exceptions and Logging
        public final static short CRITICAL = 1;
        public final static short IMPORTANT = 4;
        public final static short WARNING = 7;
        public final static short INFORMATIONAL = 10;
        public final static short DEBUG = 13;
        public final static short VERBOSE = 16;
    }

    public static String getXmlString(String inFilename) throws Exception {
        StringBuffer sb = new StringBuffer();
        BufferedReader reader = new BufferedReader(new FileReader(new File(
                inFilename)));
        try {
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            return sb.toString();
        } finally {
            reader.close();
        }
    }

}
相關文章
相關標籤/搜索