1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package org.openoffice.xmerge.util; 25 26 import org.w3c.dom.Node; 27 import org.w3c.dom.Document; 28 import org.w3c.dom.NodeList; 29 import org.w3c.dom.Element; 30 import org.w3c.dom.NamedNodeMap; 31 32 /** 33 * Class containing static util methods for handling XML trees. 34 * 35 * @author smak 36 */ 37 public final class XmlUtil { 38 39 40 /** 41 * Perform a deep clone of certain <code>Node</code> which 42 * will base on the document <code>Node</code> of the old 43 * <code>Node</code>. 44 * 45 * @param oldNode The <code>Document</code> of this 46 * <code>Node</code> is used to clone 47 * the <code>Node</code> 48 * @param newNode The <code>Node</code> to clone. 49 * 50 * @return The cloned <code>Node</code>. 51 */ deepClone(Node oldNode, Node newNode)52 public static Node deepClone(Node oldNode, Node newNode) { 53 Document docNode = oldNode.getOwnerDocument(); 54 55 // clone the starting node 56 Node clonedNode = cloneNode(docNode, newNode); 57 58 // then clone the sub-tree recursively 59 cloneTree(docNode, clonedNode, newNode); 60 61 return clonedNode; 62 } 63 64 65 /** 66 * Clone the sub-tree under certain given <code>Node</code> 67 * 68 * @param docNode The <code>Document</code> used to clone 69 * the <code>Node</code>. 70 * @param oldNode The <code>Node</code> to clone. 71 * @param newNode The destination <code>Node</code>. 72 */ cloneTree(Document docNode, Node oldNode, Node newNode)73 private static void cloneTree(Document docNode, Node oldNode, Node newNode) { 74 75 NodeList nodeList = newNode.getChildNodes(); 76 int nodeListLen = nodeList.getLength(); 77 78 for (int i = 0; i < nodeListLen; i++) { 79 Node newClonedChild = cloneNode(docNode, nodeList.item(i)); 80 if (newClonedChild != null) { 81 oldNode.appendChild(newClonedChild); 82 cloneTree(docNode, newClonedChild, nodeList.item(i)); 83 } 84 } 85 } 86 87 88 /** 89 * Clone a <code>Node</code> (either text or element). 90 * 91 * @param docNode The <code>Document</code> used to 92 * clone the <code>Node</code>. 93 * @param newNode The <code>Node</code> to clone. 94 * 95 * @return The cloned <code>Node</code>. 96 */ cloneNode(Document docNode, Node newNode)97 private static Node cloneNode(Document docNode, Node newNode) { 98 99 Node clonedNode = null; 100 101 // only support text node and element node (will copy the attributes) 102 switch (newNode.getNodeType()) { 103 case Node.TEXT_NODE: 104 String textStr = newNode.getNodeValue(); 105 clonedNode = docNode.createTextNode(textStr); 106 break; 107 case Node.ELEMENT_NODE: 108 Element oldElem = (Element)newNode; 109 String tagName = newNode.getNodeName(); 110 Element newElem = (docNode.createElement(tagName)); 111 112 // copy the attributes 113 NamedNodeMap attrs = oldElem.getAttributes(); 114 115 for (int i = 0; i < attrs.getLength(); i++) { 116 newElem.setAttribute(attrs.item(i).getNodeName(), 117 attrs.item(i).getNodeValue()); 118 } 119 clonedNode = newElem; 120 break; 121 } 122 return clonedNode; 123 } 124 125 126 /** 127 * Returns the name and type of an XML DOM <code>Node</code>. 128 * 129 * @param node <code>Node</code> to query. 130 * 131 * @return Name and type of XML DOM <code>Node</code>. 132 */ getNodeInfo(Node node)133 public static String getNodeInfo(Node node) { 134 135 String str = null; 136 switch (node.getNodeType()) { 137 138 case Node.ELEMENT_NODE: 139 str = "ELEMENT"; 140 break; 141 case Node.ATTRIBUTE_NODE: 142 str = "ATTRIBUTE"; 143 break; 144 case Node.TEXT_NODE: 145 str = "TEXT"; 146 break; 147 case Node.CDATA_SECTION_NODE: 148 str = "CDATA_SECTION"; 149 break; 150 case Node.ENTITY_REFERENCE_NODE: 151 str = "ENTITY_REFERENCE"; 152 break; 153 case Node.ENTITY_NODE: 154 str = "ENTITY"; 155 break; 156 case Node.PROCESSING_INSTRUCTION_NODE: 157 str = "PROCESSING_INSTRUCTION"; 158 break; 159 case Node.COMMENT_NODE: 160 str = "COMMENT"; 161 break; 162 case Node.DOCUMENT_NODE: 163 str = "DOCUMENT"; 164 break; 165 case Node.DOCUMENT_TYPE_NODE: 166 str = "DOCUMENT_TYPE"; 167 break; 168 case Node.DOCUMENT_FRAGMENT_NODE: 169 str = "DOCUMENT_FRAGMENT"; 170 break; 171 case Node.NOTATION_NODE: 172 str = "NOTATION"; 173 break; 174 } 175 176 StringBuffer buffer = new StringBuffer("name=\""); 177 buffer.append(node.getNodeName()); 178 buffer.append("\" type=\""); 179 buffer.append(str); 180 buffer.append("\""); 181 182 return buffer.toString(); 183 } 184 } 185 186