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(); } } }