1 46 package org.codehaus.groovy.tools.xml; 47 48 import groovy.util.IndentPrinter; 49 50 import java.io.PrintWriter ; 51 import java.util.HashMap ; 52 import java.util.Map ; 53 54 import org.w3c.dom.Attr ; 55 import org.w3c.dom.Comment ; 56 import org.w3c.dom.Document ; 57 import org.w3c.dom.Element ; 58 import org.w3c.dom.NamedNodeMap ; 59 import org.w3c.dom.Node ; 60 import org.w3c.dom.NodeList ; 61 import org.w3c.dom.ProcessingInstruction ; 62 import org.w3c.dom.Text ; 63 64 70 public class DomToGroovy { 71 72 private IndentPrinter out; 73 74 public DomToGroovy(PrintWriter out) { 75 this(new IndentPrinter(out)); 76 } 77 78 public DomToGroovy(IndentPrinter out) { 79 this.out = out; 80 } 81 82 83 public void print(Document document) { 84 printChildren(document, new HashMap ()); 85 } 86 87 protected void print(Node node, Map namespaces, boolean endWithComma) { 90 switch (node.getNodeType()) { 91 case Node.ELEMENT_NODE : 92 printElement((Element ) node, namespaces, endWithComma); 93 break; 94 case Node.PROCESSING_INSTRUCTION_NODE : 95 printPI((ProcessingInstruction ) node, endWithComma); 96 break; 97 case Node.TEXT_NODE : 98 printText((Text ) node, endWithComma); 99 break; 100 case Node.COMMENT_NODE : 101 printComment((Comment ) node, endWithComma); 102 break; 103 } 104 } 105 106 protected void printElement(Element element, Map namespaces, boolean endWithComma) { 107 namespaces = defineNamespaces(element, namespaces); 108 109 element.normalize(); 110 printIndent(); 111 112 String prefix = element.getPrefix(); 113 if (prefix != null && prefix.length() > 0) { 114 print(prefix); 115 print("."); 116 } 117 print(getLocalName(element)); 118 119 boolean hasAttributes = printAttributes(element); 120 121 NodeList list = element.getChildNodes(); 122 int length = list.getLength(); 123 if (length == 0) { 124 printEnd("", endWithComma); 125 } 126 else { 127 Node node = list.item(0); 128 if (length == 1 && node instanceof Text ) { 129 Text textNode = (Text ) node; 130 String text = getTextNodeData(textNode); 131 if (hasAttributes) { 132 print(" [\""); 133 print(text); 134 printEnd("\"]", endWithComma); 135 } 136 else { 137 print("(\""); 138 print(text); 139 printEnd("\")", endWithComma); 140 } 141 } 142 else if (mixedContent(list)) { 143 println(" ["); 144 out.incrementIndent(); 145 for (node = element.getFirstChild(); node != null; node = node.getNextSibling()) { 146 boolean useComma = node.getNextSibling() != null; 147 print(node, namespaces, useComma); 148 } 149 out.decrementIndent(); 150 printIndent(); 151 printEnd("]", endWithComma); 152 } 153 else { 154 println(" {"); 155 out.incrementIndent(); 156 printChildren(element, namespaces); 157 out.decrementIndent(); 158 printIndent(); 159 printEnd("}", endWithComma); 160 } 161 } 162 } 163 164 protected void printPI(ProcessingInstruction instruction, boolean endWithComma) { 165 printIndent(); 166 print("xml.pi('"); 167 print(instruction.getTarget()); 168 print("', '"); 169 print(instruction.getData()); 170 printEnd("');", endWithComma); 171 } 172 173 protected void printComment(Comment comment, boolean endWithComma) { 174 String text = comment.getData().trim(); 175 if (text.length() >0) { 176 printIndent(); 177 print("/* "); 178 print(text); 179 printEnd(" */", endWithComma); 180 } 181 } 182 183 protected void printText(Text node, boolean endWithComma) { 184 String text = getTextNodeData(node); 185 if (text.length() > 0) { 186 printIndent(); 187 print("\""); 191 print(text); 192 printEnd("\"", endWithComma); 193 } 194 } 195 196 protected Map defineNamespaces(Element element, Map namespaces) { 197 Map answer = null; 198 String prefix = element.getPrefix(); 199 if (prefix != null && prefix.length() > 0 && !namespaces.containsKey(prefix)) { 200 answer = new HashMap (namespaces); 201 defineNamespace(answer, prefix, element.getNamespaceURI()); 202 } 203 NamedNodeMap attributes = element.getAttributes(); 204 int length = attributes.getLength(); 205 for (int i = 0; i < length; i++) { 206 Attr attribute = (Attr ) attributes.item(i); 207 prefix = attribute.getPrefix(); 208 if (prefix != null && prefix.length() > 0 && !namespaces.containsKey(prefix)) { 209 if (answer == null) { 210 answer = new HashMap (namespaces); 211 } 212 defineNamespace(answer, prefix, attribute.getNamespaceURI()); 213 } 214 } 215 return (answer != null) ? answer : namespaces; 216 } 217 218 protected void defineNamespace(Map namespaces, String prefix, String uri) { 219 namespaces.put(prefix, uri); 220 if (!prefix.equals("xmlns") && !prefix.equals("xml")) { 221 printIndent(); 222 print(prefix); 223 print(" = xmlns.namespace('"); 224 print(uri); 225 println("')"); 226 } 227 } 228 229 protected boolean printAttributes(Element element) { 230 boolean hasAttribute = false; 231 232 NamedNodeMap attributes = element.getAttributes(); 233 int length = attributes.getLength(); 234 if (length > 0) { 235 StringBuffer buffer = new StringBuffer (); 236 for (int i = 0; i < length; i++) { 237 Attr attribute = (Attr ) attributes.item(i); 238 String prefix = attribute.getPrefix(); 239 if (prefix != null && prefix.length() > 0) { 240 if (buffer.length() > 0) { 241 buffer.append(", "); 242 } 243 buffer.append(prefix); 244 buffer.append("."); 245 buffer.append(getLocalName(attribute)); 246 buffer.append(":'"); 247 buffer.append(attribute.getValue()); 248 buffer.append("'"); 249 } 250 } 251 252 print("("); 253 for (int i = 0; i < length; i++) { 254 Attr attribute = (Attr ) attributes.item(i); 255 String prefix = attribute.getPrefix(); 256 if (prefix == null || prefix.length() == 0) { 257 if (!hasAttribute) { 258 hasAttribute = true; 259 } 260 else { 261 print(", "); 262 } 263 print(getLocalName(attribute)); 264 print(":'"); 265 print(attribute.getValue()); 266 print("'"); 267 } 268 } 269 if (buffer.length() > 0) { 270 if (hasAttribute) { 271 print(", "); 272 } 273 print("xmlns=["); 274 print(buffer.toString()); 275 print("]"); 276 hasAttribute = true; 277 } 278 print(")"); 279 } 280 return hasAttribute; 281 } 282 283 protected String getTextNodeData(Text node) { 284 String text = node.getData().trim(); 285 return text; 286 } 287 288 protected boolean mixedContent(NodeList list) { 289 boolean hasText = false; 290 boolean hasElement = false; 291 for (int i = 0, size = list.getLength(); i < size; i++) { 292 Node node = list.item(i); 293 if (node instanceof Element ) { 294 hasElement = true; 295 } 296 else if (node instanceof Text ) { 297 String text = getTextNodeData((Text ) node); 298 if (text.length() > 0) { 299 hasText = true; 300 } 301 } 302 } 303 return hasText && hasElement; 304 } 305 306 protected void printChildren(Node parent, Map namespaces) { 307 for (Node node = parent.getFirstChild(); node != null; node = node.getNextSibling()) { 308 print(node, namespaces, false); 309 } 310 } 311 312 protected String getLocalName(Node node) { 313 String answer = node.getLocalName(); 314 if (answer == null) { 315 answer = node.getNodeName(); 316 } 317 return answer.trim(); 318 } 319 320 protected void printEnd(String text, boolean endWithComma) { 321 if (endWithComma) { 322 print(text); 323 println(","); 324 } 325 else { 326 println(text); 327 } 328 } 329 330 protected void println(String text) { 331 out.println(text); } 332 333 protected void print(String text) { 334 out.print(text); 335 } 336 337 protected void printIndent() { 338 out.printIndent(); 339 } 340 } 341 | Popular Tags |