📄 xmlnotportable.java
字号:
/*------------------------------------------------------------------------------Name: XmlNotPortable.javaProject: xmlBlaster.orgCopyright: xmlBlaster.org, see xmlBlaster-LICENSE fileComment: XmlNotPortable hold none portable xml codeVersion: $Id: XmlNotPortable.java 16127 2007-04-20 08:09:47Z ruff $Author: xmlBlaster@marcelruff.info------------------------------------------------------------------------------*/package org.xmlBlaster.util;import org.w3c.dom.CDATASection;import org.w3c.dom.Comment;import org.w3c.dom.Element;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.w3c.dom.Text;import org.w3c.dom.Document;import org.xmlBlaster.util.Global;import org.xmlBlaster.util.def.ErrorCode;import java.util.logging.Logger;import java.util.logging.Level;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.util.Enumeration;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;/** * XmlNotPortable holds static methods for parser dependent code. * * Currently JDK 1.2 until JDK 1.5 are explicitly covered. * <p> * For JDK 1.5 we use only DOM Level 3 compliant coding, so any * such parser should do the job. * <p> * For JDK <= 1.4 we need the crimson parser. * <p> * The current xml code is tested with Sun JDK 1.2 - JDK 1.6 * IBM JDK 1.4 and jrockit JDK 5. * * @author <a href="mailto:xmlBlaster@marcelruff.info">Marcel Ruff</a> */public class XmlNotPortable{ private static final String ME = "XmlNotPortable"; private static Logger log = Logger.getLogger(XmlNotPortable.class.getName()); private static java.lang.reflect.Method method_newXPath = null; private static Class[] paramCls_StringDocument = null; private static Class clazz_XPathFactory = null; private static Class clazz_XPath = null; private static Class clazz_QName = null; private static Object instance_XPathFactory = null; private static Object field_NODESET = null; /** We only distinguish: * 13 for all JDK <= 1.3 * 14 for JDK 1.4 * 15 for all JDK >= 1.5 */ public static int JVM_VERSION = 14; private static int version; /** * xmlBlaster uses generally UTF-8 */ public static String ENCODING = "UTF-8"; static { String version = System.getProperty("java.specification.version"); // 1.5, use "java.vm.version=1.5.0_04"? version = (version==null)?"1.3":version.trim(); if (version.startsWith("1.1") || version.startsWith("1.2") || version.startsWith("1.3")) { JVM_VERSION = 13; } else if (version.startsWith("1.4")) { JVM_VERSION = 14; } else { JVM_VERSION = 15; // or above } } /** * Checks for forcing crimson even for JDK 15 * @return 13, 14 or 15 */ public static int getJvmXmlVersionToUse() { if (version == 0) { synchronized (XmlNotPortable.class) { if (version == 0) { version = JVM_VERSION; if ("org.apache.crimson.jaxp.DocumentBuilderFactoryImpl".equals(Global.instance().getProperty().get("javax.xml.parsers.DocumentBuilderFactory",""))) { version = 14; } // System.out.println("JVM_VERSION used for XML is " + version); } } } return version; } /** * Do XPath query on DOM */ public static Enumeration getNodeSetFromXPath(String expression, org.w3c.dom.Document document) throws XmlBlasterException { try { if (getJvmXmlVersionToUse() >= 15) { //javax.xml.xpath.XPath xpath = javax.xml.xpath.XPathFactory.newInstance().newXPath(); //final org.w3c.dom.NodeList nodes = (org.w3c.dom.NodeList)xpath.evaluate(expression, document, javax.xml.xpath.XPathConstants.NODESET); if (method_newXPath == null) { synchronized(XmlNotPortable.class) { if (method_newXPath == null) { clazz_XPathFactory = java.lang.Class.forName("javax.xml.xpath.XPathFactory"); Class[] paramCls = new Class[0]; Object[] params = new Object[0]; java.lang.reflect.Method method = clazz_XPathFactory.getMethod("newInstance", paramCls); instance_XPathFactory = method.invoke(clazz_XPathFactory, params); method_newXPath = clazz_XPathFactory.getMethod("newXPath", paramCls); clazz_XPath = java.lang.Class.forName("javax.xml.xpath.XPath"); Class clazz_XPathConstants = java.lang.Class.forName("javax.xml.xpath.XPathConstants"); clazz_QName = java.lang.Class.forName("javax.xml.namespace.QName"); java.lang.reflect.Field field = clazz_XPathConstants.getDeclaredField("NODESET"); field_NODESET = field.get(null); paramCls_StringDocument = new Class[] { java.lang.String.class, java.lang.Object.class, // org.w3c.dom.Document.class, clazz_QName }; } } } Object xpath = method_newXPath.invoke(instance_XPathFactory, new Object[0]); Object[] params = new Object[] { expression, document, field_NODESET }; java.lang.reflect.Method method_evaluate = clazz_XPath.getMethod("evaluate", paramCls_StringDocument); final org.w3c.dom.NodeList nodes = (org.w3c.dom.NodeList)method_evaluate.invoke(xpath, params); final int length = nodes.getLength(); return new java.util.Enumeration() { int i=0; public boolean hasMoreElements() { return i<length; } public Object nextElement() { i++; return nodes.item(i-1); } }; } else { // JDK < 1.5: james clark XSL parser with fujitsu wrapper for XPath: // see xmlBlaster/lib/xtdash.jar and xmlBlaster/lib/omquery.jar //com.fujitsu.xml.omquery.DomQueryMgr queryMgr = // new com.fujitsu.xml.omquery.DomQueryMgr(document); //return queryMgr.getNodesByXPath(document, expression); Class clazz = java.lang.Class.forName("com.fujitsu.xml.omquery.DomQueryMgr"); Class[] paramCls = new Class[] { org.w3c.dom.Document.class }; Object[] params = new Object[] { document }; java.lang.reflect.Constructor ctor = clazz.getConstructor(paramCls); Object domQueryMgr = ctor.newInstance(params); paramCls = new Class[] { org.w3c.dom.Node.class, java.lang.String.class }; params = new Object[] { document, expression }; java.lang.reflect.Method method = clazz.getMethod("getNodesByXPath", paramCls); return (Enumeration)method.invoke(domQueryMgr, params); } } catch (Exception e) { // javax.xml.xpath.XPathExpressionException or com.jclark.xsl.om.XSLException e.printStackTrace(); throw new XmlBlasterException(Global.instance(), ErrorCode.RESOURCE_CONFIGURATION, ME, "Can't process XPath expression '" + expression + "'", e); } } private static final java.io.ByteArrayOutputStream write(ByteArrayOutputStream out, Node node, String offset) throws IOException { final String off = "\n" + offset; if (node instanceof Element) { String name = node.getNodeName(); // String value = node.getNodeValue(); NamedNodeMap attrs = node.getAttributes(); StringBuffer buf = new StringBuffer(128); StringBuffer buf1 = new StringBuffer(50); buf.append(off).append("<").append(name); if (attrs != null && attrs.getLength() > 0) { for (int i=0; i < attrs.getLength(); i++) { Node attr = attrs.item(i); buf.append(" ").append(attr.getNodeName()).append("='").append(attr.getNodeValue()).append("'"); } } boolean hasChilds = node.hasChildNodes(); if (!hasChilds) { buf.append("/>"); out.write(buf.toString().getBytes()); } else { buf.append(">"); out.write(buf.toString().getBytes()); buf = new StringBuffer(50); buf1.append("</").append(name).append(">"); if (hasChilds) { NodeList childs = node.getChildNodes(); for (int i=0; i < childs.getLength(); i++) { Node child = childs.item(i); write(out, child, offset + " "); } buf.append(off); } buf.append(buf1); out.write(buf.toString().getBytes()); } } else if (node instanceof CDATASection) { String value = node.getNodeValue(); out.write(off.getBytes()); out.write("<![CDATA[".getBytes()); if (value != null) out.write(value.getBytes()); out.write("]]>".getBytes()); } else if (node instanceof Comment) { String value = node.getNodeValue(); out.write(off.getBytes()); out.write("<!-- ".getBytes()); if (value != null) out.write(value.getBytes()); out.write(" -->".getBytes()); } else if (node instanceof Text) { String value = node.getNodeValue(); if (value != null && value.trim().length() > 0) out.write(value.getBytes()); } return out; } public static final ByteArrayOutputStream writeNode(Node node) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); out = write(out, node, ""); out.flush(); return out; } /** * Dumo the DOM nodes to a XML string. * * (DOM) Level 1 and DOM Level 2 (The org.w3c.dom API is DOM Level 2 API) * specifications do not have a standard method for loading and saving an XML document. * Instead, we use vendor (crimson) specific code for input to and output from DOM parsers, * which is a disadvantage when portability is a requirement. */ public static final java.io.ByteArrayOutputStream write(org.w3c.dom.Node node) throws IOException { java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();/* if (getJvmXmlVersionToUse() == 13) { if (document.getClass().getName().equals("org.apache.crimson.tree.XmlDocument")) { //if (document instanceof org.apache.crimson.tree.XmlDocument) { // ((org.apache.crimson.tree.XmlDocument)document).write(out/*, encoding* /); //} try { Class[] paramCls = new Class[] { java.io.OutputStream.class }; Object[] params = new Object[] { out }; java.lang.reflect.Method method = document.getClass().getMethod("write", paramCls); method.invoke(document, params); } catch(Exception e) { e.printStackTrace(); log.error(ME, "Code to write XML-ASCII has failed for document class=" + document.getClass().getName() + ": " + e.toString()); } } return out; }*/ if (getJvmXmlVersionToUse() == 14) { // see http://java.sun.com/xml/jaxp/dist/1.1/docs/tutorial/xslt/2_write.html try { if (log.isLoggable(Level.FINE)) log.fine("write - Using JDK 1.4 DOM implementation"); javax.xml.transform.TransformerFactory tf = javax.xml.transform.TransformerFactory.newInstance(); javax.xml.transform.Transformer t = tf.newTransformer(); // t.setOutputProperty(javax.xml.transform.OutputKeys.DOCTYPE_SYSTEM, PROPS_DTD_URI); t.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes"); t.setOutputProperty(javax.xml.transform.OutputKeys.METHOD, "xml"); t.setOutputProperty(javax.xml.transform.OutputKeys.ENCODING, ENCODING); //t.setOutputProperty(javax.xml.transform.OutputKeys.CDATA_SECTION_ELEMENTS, ""); t.transform(new javax.xml.transform.dom.DOMSource(node), new javax.xml.transform.stream.StreamResult(out)); } catch(Exception e) { e.printStackTrace(); log.severe("Code to write XML-ASCII has failed for document class=" + node.getClass().getName() + ": " + e.toString()); } return out; } try { if (log.isLoggable(Level.FINE)) log.fine("write - Using JDK 1.5 DOM implementation"); // JDK 1.5 DOM Level 3 conforming: /* Works only with lib/ant/xercesImpl.jar in the CLASSPATH org.w3c.dom.ls.DOMImplementationLS implls = (org.w3c.dom.ls.DOMImplementationLS)document.getImplementation(); // The above downcast throws a java.lang.ClassCastException for JDK 1.4, but is fine for JDK 1.5 org.w3c.dom.ls.LSSerializer domWriter = implls.createLSSerializer(); //domWriter.setNewLine("\n"); // should be default //domWriter.setFilter(new org.w3c.dom.ls.LSSerializerFilter () { // public int getWhatToShow() { // return SHOW_ALL; // } // public short acceptNode(org.w3c.dom.Node n) { // return FILTER_ACCEPT; // } //}); org.w3c.dom.ls.LSOutput output=implls.createLSOutput(); output.setByteStream(out); output.setEncoding(ENCODING); domWriter.write(document, output); //String tmp = domWriter.writeToString(document); //out.write(tmp.getBytes()); */ Class clazz_DOMImplementationLS = java.lang.Class.forName("org.w3c.dom.ls.DOMImplementationLS"); /* org.w3c.dom.ls.DOMImplementationLS */ Object implls = null; if (node instanceof Document) implls = ((Document)node).getImplementation(); else implls = node.getOwnerDocument().getImplementation();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -