📄 xmlnotportable.java
字号:
Class[] paramCls = new Class[0]; Object[] params = new Object[0]; java.lang.reflect.Method method_createLSSerializer = clazz_DOMImplementationLS.getMethod("createLSSerializer", paramCls); java.lang.reflect.Method method_createLSOutput = clazz_DOMImplementationLS.getMethod("createLSOutput", paramCls); /* org.w3c.dom.ls.LSSerializer */ Object domWriter = method_createLSSerializer.invoke(implls, params); /* org.w3c.dom.ls.LSOutput */ Class clazz_LSOutput = java.lang.Class.forName("org.w3c.dom.ls.LSOutput"); Object output = method_createLSOutput.invoke(implls, params); paramCls = new Class[] { java.io.OutputStream.class }; params = new Object[] { out }; java.lang.reflect.Method method_setByteStream = clazz_LSOutput.getMethod("setByteStream", paramCls); method_setByteStream.invoke(output, params); paramCls = new Class[] { java.lang.String.class }; params = new Object[] { ENCODING }; java.lang.reflect.Method method_setEncoding = clazz_LSOutput.getMethod("setEncoding", paramCls); method_setEncoding.invoke(output, params); paramCls = new Class[] { org.w3c.dom.Node.class, clazz_LSOutput }; params = new Object[] { node, output }; java.lang.reflect.Method method_write = domWriter.getClass().getMethod("write", paramCls); method_write.invoke(domWriter, params); } catch(Exception e) { e.printStackTrace(); log.severe("Code to write XML-ASCII has failed for document class=" + node.getClass().getName() + ": " + e.toString()); } /* NEW: xerces 2x (=IBM xml4j 4.0.1) 2002-04-18 -> samples/dom/GetElementsByTagName.java shows how to dump XML our self -> samples/dom/Writer.java shows how to dump XML our self or use this Apache specific code: else if (document instanceof org.apache.xerces.dom.DocumentImpl) { import org.apache.xml.serialize.OutputFormat; import org.apache.xml.serialize.Serializer; import org.apache.xml.serialize.SerializerFactory; import org.apache.xml.serialize.XMLSerializer; ... import org.w3c.dom.Document; Document doc= ... ... OutputFormat format = new OutputFormat( doc ); //Serialize DOM StringWriter stringOut = new StringWriter(); //Writer will be a String XMLSerializer serial = new XMLSerializer( stringOut, format ); serial.asDOMSerializer(); // As a DOM Serializer serial.serialize( doc.getDocumentElement() ); System.out.println( "STRXML = " + stringOut.toString() ); //Spit out DOM as a String */ /* // import java.io.IOException; // import java.io.StringWriter; // import org.apache.xalan.xpath.xml.FormatterToXML; // import org.apache.xml.serialize.OutputFormat; try { StringWriter stringWriter = new StringWriter(); FormatterToXML serializer = new FormatterToXML(stringWriter); OutputFormat xmlOutputFormat = new OutputFormat(); xmlOutputFormat.setOmitXMLDeclaration(true); xmlOutputFormat.setIndent(true); xmlOutputFormat.setIndentAmount(2); serializer.setOutputFormat(xmlOutputFormat); serializer.serialize(xmlKeyDoc); } catch (IOException ioException) { ioException.printStackTrace(); // handle exception } */ return out; } /** * Merging a node into another document. * <p /> * The caller must synchronize if necessary * <p /> * Implementation details: * <ol> * <li>adoptNode(): * Node org.w3c.dom.Document.adoptNode(Node source) throws DOMException * merges the nodes since JDK 1.5 / DOM Level 3 * </li> * <li>importNode(): * Node org.w3c.dom.Document.importNode(Node importedNode, boolean deep) throws DOMException * takes a clone, since JDK 1.4 / DOM Level 2 * </li> * <li>changeNodeOwner(): * Specific for crimson xml parser which was default in JDK 1.4 (not portable) * </li> * </ol> * @param the destination document * @param the node to merge into the DOM tree, it is invalid after this call * @return The node added or null */ public static final org.w3c.dom.Node mergeNode(org.w3c.dom.Document document, org.w3c.dom.Node node) { if (log.isLoggable(Level.FINER)) log.finer("mergeNode()"); if (log.isLoggable(Level.FINEST)) log.finest("mergeNode=" + node.toString()); if (getJvmXmlVersionToUse() == 13 || getJvmXmlVersionToUse() == 14) { //if (document instanceof org.apache.crimson.tree.XmlDocument) { if (document.getClass().getName().equals("org.apache.crimson.tree.XmlDocument")) { //((org.apache.crimson.tree.XmlDocument)document).changeNodeOwner(node); // not DOM portable try { Class[] paramCls = new Class[] { org.w3c.dom.Node.class }; Object[] params = new Object[] { node }; java.lang.reflect.Method method = document.getClass().getMethod("changeNodeOwner", paramCls); method.invoke(document, params); return document.getDocumentElement().appendChild(node); } catch(Exception e) { log.severe("Code to merge XML-documents adoptNode() has failed for document class=" + document.getClass().getName() + ": " + e.toString()); } } else { log.severe("Code to merge XML-documents is missing for document class=" + document.getClass().getName()); } return null; } try { if (log.isLoggable(Level.FINE)) log.fine("mergeNode - Using JDK 1.5 DOM implementation"); // DOM Level 3 WD - Experimental // com/sun/org/apache/xerces/internal/dom/CoreDocumentImpl.adoptNode() // Changes the ownerDocument of a node, its children, as well as the attached attribute nodes if there are any. // This effectively allows moving a subtree from one document to another (unlike importNode() which create a copy of the source node instead of moving it). // Note: This failed as our attribute value got lost (2006-02-07 marcel): // Befor: <key oid="aTopic"><AA name="HELLO"/></key> // After: <key oid="aTopic"><AA name=""/></key> // but never happenend again after changes (did we remerge an invalid DOM?) //document.adoptNode(node); -> Use reflection for backward compatibility /* Class[] paramCls = new Class[] { org.w3c.dom.Node.class }; Object[] params = new Object[] { node }; java.lang.reflect.Method method = document.getClass().getMethod("adoptNode", paramCls); method.invoke(document, params); return document.getDocumentElement().appendChild(node); */ // importNode introduced in DOM Level 2 // It makes a deep clone and is slower // The source node is not altered or removed from the original document; // this method creates a new copy of the source node. //Class[] paramCls = new Class[] { org.w3c.dom.Node.class, boolean.class }; //Object[] params = new Object[] { node, Boolean.TRUE }; //java.lang.reflect.Method method = document.getClass().getMethod("importNode", paramCls); //method.invoke(document, params); org.w3c.dom.Node newNode = document.importNode(node, true); return document.getDocumentElement().appendChild(newNode); } catch(/*org.w3c.dom.DOMException*/Exception e) { log.severe("Code to merge XML-documents adoptNode() has failed for document class=" + document.getClass().getName() + ": " + e.toString()); } return null; } /** * Access a XML DOM node tree walker. * Caution: Works only with JDK 1.5 or higher * @param document The DOM document * @param node The root node to walk, if null the document's top node is chosen * @throws IllegalArgumentException for JDK <= 1.4 */ public static final org.w3c.dom.traversal.TreeWalker getTreeWalker(org.w3c.dom.Document document, org.w3c.dom.Node node) { if (log.isLoggable(Level.FINER)) log.finer("getTreeWalker()"); if (node == null) { node = document.getFirstChild(); } if (getJvmXmlVersionToUse() == 13 || getJvmXmlVersionToUse() == 14) { // Not possible as crimson does not implement interface org.w3c.dom.traversal.TreeWalker! //org.apache.crimson.tree.TreeWalker tw = new org.apache.crimson.tree.TreeWalker(firstNode); //return tw; //throw new XmlBlasterException(Global.instance(), ErrorCode.INTERNAL_NOTIMPLEMENTED, "XmlNotPortable", // "XML TreeWalker is only available for JDK 1.5 or above"); throw new IllegalArgumentException("XML TreeWalker is only available for JDK 1.5 or above"); } // org/w3c/dom/traversal/TreeWalker.java DOM Level 2 org.w3c.dom.traversal.DocumentTraversal traveller = (org.w3c.dom.traversal.DocumentTraversal)document; org.w3c.dom.traversal.TreeWalker tw = traveller.createTreeWalker(node, org.w3c.dom.traversal.NodeFilter.SHOW_ALL, null, true); return tw; } /** * Encapsulate the given string with CDATA, escapes "]]>" tokens in str. * Please use for dumps only as it can't handle internally used ]]> * (no Base64 encoding is done) */ public static String escape(String str) { // TODO: Move to something like a XmlUtil class int protect = protectionNeeded(str); if (protect == 0) return str; if (protect == 2) { //System.out.println("Can't handle strings containing a CDATA end" // + " section ']]>', as i won't make Base64"); //return str; } str = (str == null) ? "" : str; int index; while ((index = str.indexOf("]]>")) != -1) { String tmp = str; str = tmp.substring(0, index + 2); str += ">"; str += tmp.substring(index + 3); //Thread.dumpStack(); //System.out.println("Can't handle strings containing a CDATA end" // + " section ']]>', i'll escape it to: " + str); } return "<![CDATA[" + str + "]]>"; } /** * If value contains XML harmful characters it needs to be * wrapped by CDATA or encoded to Base64. * @param value The string to verify * @return 0 No protection necessary * 1 Protection with CDATA is needed * 2 Protection with Base64 is needed */ public static int protectionNeeded(String value) { // TODO: Move to something like a XmlUtil class /* Handle other special characters private static final char[] NULL = "�".toCharArray(); private static final char[] AMP = "&".toCharArray(); private static final char[] LT = "<".toCharArray(); private static final char[] GT = ">".toCharArray(); private static final char[] SLASH_R = "
".toCharArray(); private static final char[] QUOT = """.toCharArray(); private static final char[] APOS = "'".toCharArray(); private static final char[] CLOSE = "</".toCharArray(); */ if (value == null) return 0; if (value.indexOf("]]>") >= 0) return 2; for (int i=0; i<value.length(); i++) { int c = value.charAt(i); if (c == '<' || c == '&') return 1; } return 0; } /* * Replacing a node (located within a certain DOM hierachy) with an other * one * <p /> * The caller must synchronize if necessary * @param oldNode the node to be replaced * @param newNode the node to put in place of the old node public static final void replaceNode(org.w3c.dom.Node oldNode, org.w3c.dom.Node newNode) { if (log.isLoggable(Level.FINE)) log.trace(ME, "replaceNode=" + oldNode.toString()); org.w3c.dom.Document document = oldNode.getOwnerDocument(); if (document instanceof org.apache.crimson.tree.XmlDocument) { ((org.apache.crimson.tree.XmlDocument)document).changeNodeOwner(newNode); // not DOM portable } else { log.error(ME, "Code to replace XML-nodes is missing for document class=" + document.getClass().getName()); } org.w3c.dom.Node parentNode = oldNode.getParentNode(); if (parentNode == null) { document.getDocumentElement().appendChild(newNode); document.getDocumentElement().removeChild(oldNode); } else { parentNode.appendChild(newNode); parentNode.removeChild(oldNode); } if (log.isLoggable(Level.FINE)) log.trace(ME, "Successfully replaced node"); } */ // java org.xmlBlaster.util.XmlNotPortable public static void main(String[] args) { Global glob = new Global(args); // Instantiate the xmlBlaster DOM tree with <xmlBlaster> root node (DOM portable) org.w3c.dom.Document bigDoc = null; String xml = "<?xml version='1.0' encoding='ISO-8859-1' ?>\n" + "<xmlBlaster></xmlBlaster>"; java.io.StringReader reader = new java.io.StringReader(xml); org.xml.sax.InputSource input = new org.xml.sax.InputSource(reader); try { DocumentBuilderFactory dbf = glob.getDocumentBuilderFactory(); //dbf.setNamespaceAware(true); //dbf.setCoalescing(true); //dbf.setValidating(false); //dbf.setIgnoringComments(true); DocumentBuilder db = dbf.newDocumentBuilder (); bigDoc = db.parse(input); } catch (Exception e) { e.printStackTrace(); } xml = "<key oid='aTopic'><AA name='HELLO'/></key>"; try { XmlToDom dom = new XmlToDom(glob, xml); System.out.println("Before merge: " + dom.domToXml("")); org.w3c.dom.Node newNode = XmlNotPortable.mergeNode(bigDoc, dom.getRootNode()); //org.w3c.dom.Node newNode = bigDoc.importNode(dom.getRootNode(), true); //bigDoc.getDocumentElement().appendChild(newNode); //bigDoc.adoptNode(dom.getRootNode()); System.out.println("After merge: " + XmlNotPortable.write(newNode)); System.out.println("After merge complete: " + XmlNotPortable.write(bigDoc)); } catch (Exception e) { e.printStackTrace(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -