一、前言
关于empire-db源码包中org.apache.empire.xml.XMLUtil、org.apache.empire.xml.XMLWriter工具相关类,对XML及节点元素获取解析、插入追加元素处理等。
二、源码说明
1.XMLUtil工具类
package org.apache.empire.xml;@b@@b@import java.util.Map;@b@import java.util.Map.Entry;@b@import javax.xml.parsers.DocumentBuilder;@b@import javax.xml.parsers.DocumentBuilderFactory;@b@import javax.xml.parsers.ParserConfigurationException;@b@import org.slf4j.Logger;@b@import org.slf4j.LoggerFactory;@b@import org.w3c.dom.Attr;@b@import org.w3c.dom.Document;@b@import org.w3c.dom.Element;@b@import org.w3c.dom.NamedNodeMap;@b@import org.w3c.dom.Node;@b@import org.w3c.dom.NodeList;@b@@b@public class XMLUtil@b@{@b@ protected static final Logger log = LoggerFactory.getLogger(XMLUtil.class);@b@ private static DocumentBuilder documentBuilder = null;@b@@b@ public static synchronized Document createDocument()@b@ {@b@ return documentBuilder.newDocument();@b@ }@b@@b@ public static DocumentBuilder getDocumentBuilder()@b@ {@b@ return documentBuilder;@b@ }@b@@b@ public static synchronized Element createDocument(String rootElemName)@b@ {@b@ Document doc = createDocument();@b@ Element root = doc.createElement(rootElemName);@b@ doc.appendChild(root);@b@ return root;@b@ }@b@@b@ public static synchronized Element createDocumentNS(String prefix, String rootElemName, Map<String, String> nsMap)@b@ {@b@ Document doc = createDocument();@b@@b@ Element root = null;@b@ if ((prefix != null) && (prefix.length() > 0))@b@ {@b@ String uri = (String)nsMap.get(prefix);@b@ if (uri == null)@b@ {@b@ log.error("Namespace URI for namespace " + prefix + " not found!");@b@ return null;@b@ }@b@@b@ root = doc.createElementNS(uri, prefix + ":" + rootElemName);@b@ }@b@ else@b@ {@b@ root = doc.createElement(rootElemName);@b@ }@b@ doc.appendChild(root);@b@@b@ addNamespaceURIs(doc, nsMap);@b@ return root;@b@ }@b@@b@ public static boolean addNamespaceURIs(Document doc, Map<String, String> nsMap)@b@ {@b@ Element root = doc.getDocumentElement();@b@ if (root == null)@b@ return false;@b@@b@ for (Map.Entry entry : nsMap.entrySet())@b@ {@b@ root.setAttribute("xmlns:" + ((String)entry.getKey()), (String)entry.getValue());@b@ }@b@ return true;@b@ }@b@@b@ public static String getNamespaceURI(Document doc, String prefix)@b@ {@b@ Element e = doc.getDocumentElement();@b@ return e.getAttributeNS("", prefix);@b@ }@b@@b@ public static Element getFirstChild(Node parent)@b@ {@b@ if (parent == null)@b@ return null;@b@ Node node = parent.getFirstChild();@b@ while (node != null)@b@ {@b@ if (node.getNodeType() == 1)@b@ return ((Element)node);@b@ node = node.getNextSibling();@b@ }@b@ return null;@b@ }@b@@b@ public static Element findFirstChild(Node parent, String tagName)@b@ {@b@ if (parent == null)@b@ return null;@b@ Node node = parent.getFirstChild();@b@ while (node != null)@b@ {@b@ if (node.getNodeType() == 1)@b@ {@b@ Element elem = (Element)node;@b@ if (tagName.equalsIgnoreCase(elem.getTagName()))@b@ return elem;@b@ }@b@ node = node.getNextSibling();@b@ }@b@ return null;@b@ }@b@@b@ public static Element getNextSiblingElement(Element child, boolean sameName)@b@ {@b@ if (child == null)@b@ return null;@b@ String name = child.getTagName();@b@ Node node = child.getNextSibling();@b@ while (node != null)@b@ {@b@ if (node.getNodeType() == 1)@b@ {@b@ Element elem = (Element)node;@b@ if ((sameName) && (name.equalsIgnoreCase(elem.getTagName())))@b@ return elem;@b@ }@b@ node = node.getNextSibling();@b@ }@b@ return null;@b@ }@b@@b@ public static Element findFirstChildWithAttrib(Node parent, String tagName, String attrName, Object value)@b@ {@b@ Element elem = findFirstChild(parent, tagName);@b@ if (attrName == null)@b@ return null;@b@ while (elem != null)@b@ {@b@ String attrValue = elem.getAttribute(attrName);@b@ if ((attrValue == null) || (attrValue.length() < 1))@b@ {@b@ if (value != null) break label64;@b@ break;@b@ }@b@@b@ if (attrValue.equals(value.toString())) {@b@ break;@b@ }@b@@b@ label64: elem = getNextSiblingElement(elem, true);@b@ }@b@ return elem;@b@ }@b@@b@ public static Element findFirstChildDeep(Element parent, String tagName)@b@ {@b@ if (parent == null)@b@ return null;@b@ NodeList nl = parent.getElementsByTagName(tagName);@b@ for (int i = 0; i < nl.getLength(); ++i)@b@ {@b@ if (nl.item(i).getNodeType() == 1)@b@ return ((Element)nl.item(i));@b@ }@b@ return null;@b@ }@b@@b@ public static Element findFirstChildDeep(Document doc, String tagName)@b@ {@b@ if (doc == null)@b@ return null;@b@ return findFirstChildDeep(doc.getDocumentElement(), tagName);@b@ }@b@@b@ public static String getElementText(Node elem)@b@ {@b@ String value = null;@b@ Node node = (elem != null) ? elem.getFirstChild() : null;@b@@b@ while (node != null)@b@ {@b@ if (node.getNodeType() == 3)@b@ {@b@ if (value == null)@b@ value = node.getNodeValue();@b@ else@b@ value = value + node.getNodeValue();@b@ }@b@ node = node.getNextSibling();@b@ }@b@ return value;@b@ }@b@@b@ public static boolean setElementText(Node elem, Object text)@b@ {@b@ if (elem == null)@b@ return false;@b@@b@ Node node = elem.getFirstChild();@b@ while (node != null)@b@ {@b@ if (node.getNodeType() == 3)@b@ break;@b@ node = node.getNextSibling();@b@ }@b@ if (node != null)@b@ {@b@ if (text != null)@b@ node.setNodeValue(text.toString());@b@ else@b@ elem.removeChild(node);@b@ }@b@ else if (text != null)@b@ {@b@ elem.appendChild(elem.getOwnerDocument().createTextNode(text.toString()));@b@ }@b@ return true;@b@ }@b@@b@ public static Element addElement(Node parent, String name, String value)@b@ {@b@ if (parent == null)@b@ return null;@b@@b@ if (name.indexOf(32) >= 0)@b@ name = name.replace(' ', '_');@b@@b@ Element child = parent.getOwnerDocument().createElement(name);@b@ if (value != null)@b@ setElementText(child, value);@b@ parent.appendChild(child);@b@ return child;@b@ }@b@@b@ public static Element addElement(Element parent, String name)@b@ {@b@ return addElement(parent, name, null);@b@ }@b@@b@ public static Element addElementNS(Node parent, String prefix, String name, String value)@b@ {@b@ if (parent == null)@b@ return null;@b@@b@ if ((prefix == null) || (prefix.length() == 0))@b@ return addElement(parent, name, value);@b@@b@ Document doc = parent.getOwnerDocument();@b@ String uri = getNamespaceURI(doc, prefix);@b@ if (uri == null)@b@ {@b@ log.error("Namespace URI for namespace " + prefix + " not found!");@b@ return null;@b@ }@b@ Element child = doc.createElementNS(uri, prefix + ":" + name);@b@ if (value != null)@b@ setElementText(child, value);@b@ parent.appendChild(child);@b@ return child;@b@ }@b@@b@ public static Element addElementNS(Element parent, String prefix, String name)@b@ {@b@ return addElementNS(parent, prefix, name, null);@b@ }@b@@b@ public static Element insertElement(Node parent, String name, String value, Element pos)@b@ {@b@ if (parent == null)@b@ return null;@b@ Element child = parent.getOwnerDocument().createElement(name);@b@ if (value != null)@b@ setElementText(child, value);@b@@b@ parent.insertBefore(child, pos);@b@ return child;@b@ }@b@@b@ public static Element insertElement(Node parent, String name, Element pos)@b@ {@b@ return insertElement(parent, name, null, pos);@b@ }@b@@b@ public static Element insertElementNS(Node parent, String prefix, String name, String value, Element pos)@b@ {@b@ if (parent == null)@b@ return null;@b@@b@ if ((prefix == null) || (prefix.length() == 0))@b@ return insertElement(parent, name, value, pos);@b@@b@ Document doc = parent.getOwnerDocument();@b@ String uri = getNamespaceURI(doc, prefix);@b@ if (uri == null)@b@ {@b@ log.error("Namespace URI for namespace " + prefix + " not found!");@b@ return null;@b@ }@b@ Element child = doc.createElementNS(uri, prefix + ":" + name);@b@ if (value != null)@b@ setElementText(child, value);@b@@b@ parent.insertBefore(child, pos);@b@ return child;@b@ }@b@@b@ public static Element insertElementNS(Node parent, String prefix, String name, Element pos)@b@ {@b@ return insertElementNS(parent, prefix, name, null, pos);@b@ }@b@@b@ public static String getChildText(Node parent, String childName)@b@ {@b@ Element elem = findFirstChild(parent, childName);@b@ if (elem == null)@b@ return null;@b@ return getElementText(elem);@b@ }@b@@b@ public static boolean changeTagName(Element elem, String newName)@b@ {@b@ if (elem == null)@b@ return false;@b@ Document doc = elem.getOwnerDocument();@b@ Element newElem = doc.createElement(newName);@b@@b@ NamedNodeMap attrs = elem.getAttributes();@b@ for (int i = 0; i < attrs.getLength(); ++i)@b@ {@b@ Attr attr2 = (Attr)doc.importNode(attrs.item(i), true);@b@ newElem.getAttributes().setNamedItem(attr2);@b@ }@b@@b@ for (Node node = elem.getFirstChild(); node != null; node = node.getNextSibling())@b@ newElem.appendChild(node.cloneNode(true));@b@@b@ Node parent = elem.getParentNode();@b@ parent.replaceChild(newElem, elem);@b@ return true;@b@ }@b@@b@ static@b@ {@b@ DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();@b@@b@ dFactory.setNamespaceAware(true);@b@ try@b@ {@b@ documentBuilder = dFactory.newDocumentBuilder();@b@ }@b@ catch (ParserConfigurationException e) {@b@ log.error("XMLUtil::createDocument-->", e);@b@ e.printStackTrace();@b@ }@b@ }@b@}
2.XMLWriter类
package org.apache.empire.xml;@b@@b@import java.io.File;@b@import java.io.FileOutputStream;@b@import java.io.IOException;@b@import java.io.OutputStream;@b@import java.io.OutputStreamWriter;@b@import java.io.PrintWriter;@b@import java.io.UnsupportedEncodingException;@b@import java.io.Writer;@b@import javax.xml.transform.Transformer;@b@import javax.xml.transform.TransformerFactory;@b@import javax.xml.transform.dom.DOMSource;@b@import javax.xml.transform.stream.StreamResult;@b@import org.slf4j.Logger;@b@import org.slf4j.LoggerFactory;@b@import org.w3c.dom.Attr;@b@import org.w3c.dom.Document;@b@import org.w3c.dom.NamedNodeMap;@b@import org.w3c.dom.Node;@b@import org.w3c.dom.NodeList;@b@@b@public class XMLWriter@b@{@b@ protected static final Logger log = LoggerFactory.getLogger(XMLWriter.class);@b@ protected PrintWriter out;@b@ protected boolean canonical;@b@ private static String xmlWriterRoot = null;@b@ private String charsetEncoding;@b@@b@ public static void debug(Document doc)@b@ {@b@ XMLWriter dbg = new XMLWriter(System.out);@b@ dbg.print(doc);@b@ }@b@@b@ public static void debugToFile(Document doc, String filename)@b@ {@b@ String styleSheet = "../" + filename.substring(0, filename.length() - 3) + "xslt";@b@@b@ FileOutputStream fileOutputStream = null;@b@ try@b@ {@b@ File file = new File(xmlWriterRoot, filename);@b@ if (file.exists() == true)@b@ {@b@ file.delete();@b@ }@b@@b@ fileOutputStream = new FileOutputStream(file);@b@@b@ XMLWriter dbg = new XMLWriter(fileOutputStream);@b@ dbg.print(doc, styleSheet);@b@ }@b@ catch (IOException ioe) {@b@ log.error("Error: Could not write XML to file: " + filename + " in directory: " + xmlWriterRoot);@b@ }@b@ finally@b@ {@b@ try {@b@ if (fileOutputStream != null)@b@ {@b@ fileOutputStream.close();@b@ }@b@ }@b@ catch (IOException ioe) {@b@ log.error("Cannot write Document file", ioe);@b@ }@b@ }@b@ }@b@@b@ public static void saveAsFile(Document doc, String filename)@b@ {@b@ File file;@b@ try@b@ {@b@ file = new File(filename);@b@ if (file.exists() == true)@b@ {@b@ file.delete();@b@ }@b@@b@ DOMSource domSource = new DOMSource(doc);@b@ StreamResult streamResult = new StreamResult(file);@b@@b@ TransformerFactory transformerFactory = TransformerFactory.newInstance();@b@ Transformer trf = transformerFactory.newTransformer();@b@ trf.transform(domSource, streamResult);@b@ }@b@ catch (Exception ex)@b@ {@b@ log.error("Error: Could not write XML to file: " + filename);@b@ }@b@ }@b@@b@ public static void setXmlWriterDebugPath(String path)@b@ {@b@ xmlWriterRoot = path;@b@ }@b@@b@ public XMLWriter(Writer writer, String charsetEncoding)@b@ {@b@ this.charsetEncoding = "utf-8";@b@@b@ this.out = new PrintWriter(writer);@b@ this.charsetEncoding = charsetEncoding;@b@ this.canonical = false;@b@ }@b@@b@ public XMLWriter(OutputStream outStream, String charsetEncoding)@b@ throws UnsupportedEncodingException@b@ {@b@ this(new OutputStreamWriter(outStream, charsetEncoding), charsetEncoding);@b@ }@b@@b@ public XMLWriter(OutputStream outStream)@b@ {@b@ this.charsetEncoding = "utf-8";@b@ try@b@ {@b@ this.charsetEncoding = "utf-8";@b@ this.out = new PrintWriter(new OutputStreamWriter(outStream, this.charsetEncoding));@b@ this.canonical = false;@b@ }@b@ catch (UnsupportedEncodingException e) {@b@ log.error("The encoding \"" + this.charsetEncoding + "\" is not supported!", e);@b@ }@b@ }@b@@b@ public int print(Node node, int level)@b@ {@b@ if (node == null)@b@ {@b@ return 0;@b@ }@b@@b@ int type = node.getNodeType();@b@ switch (type)@b@ {@b@ case 9:@b@ print(((Document)node).getDocumentElement(), 0);@b@@b@ break;@b@ case 1:@b@ this.out.print('<');@b@ this.out.print(node.getNodeName());@b@ Attr[] attrs = sortAttributes(node.getAttributes());@b@ for (int i = 0; i < attrs.length; ++i)@b@ {@b@ Attr attr = attrs[i];@b@ this.out.print(' ');@b@ this.out.print(attr.getNodeName());@b@ this.out.print("=\"");@b@ this.out.print(normalize(attr.getNodeValue()));@b@ this.out.print('"');@b@ }@b@@b@ NodeList children = node.getChildNodes();@b@ if (children != null)@b@ {@b@ int s;@b@ int len = children.getLength();@b@ if ((len > 0) && (children.item(0).getNodeType() != 3))@b@ this.out.println('>');@b@ else@b@ this.out.print('>');@b@@b@ int prevType = 0;@b@ for (int i = 0; i < len; ++i)@b@ {@b@ int s;@b@ if ((i > 0) || (children.item(i).getNodeType() != 3))@b@ {@b@ for (s = 0; s < level; ++s)@b@ this.out.print(" ");@b@ }@b@@b@ prevType = print(children.item(i), level + 1);@b@ }@b@@b@ if ((len > 0) && (prevType != 3))@b@ {@b@ for (s = 1; s < level; ++s)@b@ this.out.print(" ");@b@ }@b@ this.out.print("</");@b@ this.out.print(node.getNodeName());@b@ this.out.println('>');@b@ }@b@ else {@b@ this.out.println("/>"); }@b@ break;@b@ case 5:@b@ NodeList children;@b@ int i;@b@ if (this.canonical)@b@ {@b@ children = node.getChildNodes();@b@ if (children != null)@b@ {@b@ int len = children.getLength();@b@ for (i = 0; i < len; ++i)@b@ {@b@ print(children.item(i), level + 1);@b@ }@b@ }@b@ }@b@ else@b@ {@b@ this.out.print('&');@b@ this.out.print(node.getNodeName());@b@ this.out.print(';');@b@ }@b@ break;@b@ case 4:@b@ if (!(this.canonical))@b@ {@b@ this.out.print("<![CDATA[");@b@ this.out.print(node.getNodeValue());@b@ this.out.println("]]>");@b@ }@b@ else {@b@ this.out.print(normalize(node.getNodeValue())); }@b@ break;@b@ case 3:@b@ this.out.print(normalize(node.getNodeValue()));@b@ break;@b@ case 7:@b@ this.out.print("<?");@b@ this.out.print(node.getNodeName());@b@ String data = node.getNodeValue();@b@ if ((data != null) && (data.length() > 0))@b@ {@b@ this.out.print(' ');@b@ this.out.print(data);@b@ }@b@ this.out.println("?>");@b@ case 2:@b@ case 6:@b@ case 8:@b@ }@b@ this.out.flush();@b@ return type;@b@ }@b@@b@ public void print(Document doc)@b@ {@b@ print(doc, null);@b@ }@b@@b@ public void print(Document doc, String styleSheet)@b@ {@b@ if (!(this.canonical))@b@ {@b@ this.out.println("<?xml version=\"1.0\" encoding=\"" + this.charsetEncoding + "\"?>");@b@ }@b@ if (styleSheet != null)@b@ {@b@ this.out.print("<?xml-stylesheet type=\"text/xsl\" href=\"");@b@ this.out.print(styleSheet);@b@ this.out.println("\"?>");@b@ }@b@@b@ print(doc.getDocumentElement(), 0);@b@ this.out.flush();@b@ }@b@@b@ protected Attr[] sortAttributes(NamedNodeMap attrs)@b@ {@b@ int len = (attrs != null) ? attrs.getLength() : 0;@b@ Attr[] array = new Attr[len];@b@ for (int i = 0; i < len; ++i)@b@ {@b@ array[i] = ((Attr)attrs.item(i));@b@ }@b@ for (i = 0; i < len - 1; ++i)@b@ {@b@ String name = array[i].getNodeName();@b@ int index = i;@b@ for (int j = i + 1; j < len; ++j)@b@ {@b@ String curName = array[j].getNodeName();@b@ if (curName.compareTo(name) < 0)@b@ {@b@ name = curName;@b@ index = j;@b@ }@b@ }@b@ if (index != i)@b@ {@b@ Attr temp = array[i];@b@ array[i] = array[index];@b@ array[index] = temp;@b@ }@b@ }@b@@b@ return array;@b@ }@b@@b@ protected String normalize(String s)@b@ {@b@ return normalize(s, this.canonical);@b@ }@b@@b@ public static String normalize(String s, boolean canonical)@b@ {@b@ StringBuilder str = new StringBuilder();@b@@b@ int len = (s != null) ? s.length() : 0;@b@ for (int i = 0; i < len; ++i)@b@ {@b@ char ch = s.charAt(i);@b@ switch (ch)@b@ {@b@ case '<':@b@ str.append("<");@b@ break;@b@ case '>':@b@ str.append(">");@b@ break;@b@ case '&':@b@ str.append("&");@b@ break;@b@ case '"':@b@ str.append(""");@b@ break;@b@ case '\n':@b@ case '\r':@b@ if (canonical)@b@ {@b@ str.append("&#");@b@ str.append(Integer.toString(ch));@b@ str.append(';'); }@b@ break;@b@ default:@b@ str.append(ch);@b@ }@b@@b@ }@b@@b@ return str.toString();@b@ }@b@}