1 57 58 package org.apache.soap.util.xml; 59 60 import java.io.*; 61 import java.util.*; 62 import org.w3c.dom.*; 63 import org.apache.soap.util.*; 64 65 74 public class DOM2Writer 75 { 76 79 private static String NS_URI_XMLNS = "http://www.w3.org/2000/xmlns/"; 80 81 84 public static String nodeToString(Node node) 85 { 86 StringWriter sw = new StringWriter(); 87 88 serializeAsXML(node, sw); 89 90 return sw.toString(); 91 } 92 93 96 public static void serializeAsXML(Node node, Writer writer) 97 { 98 print(node, null, new PrintWriter(writer)); 99 } 100 101 private static void print(Node node, ObjectRegistry namespaceStack, 102 PrintWriter out) 103 { 104 if (node == null) 105 { 106 return; 107 } 108 109 boolean hasChildren = false; 110 int type = node.getNodeType(); 111 112 switch (type) 113 { 114 case Node.DOCUMENT_NODE : 115 { 116 out.println("<?xml version=\"1.0\"?>"); 117 118 NodeList children = node.getChildNodes(); 119 120 if (children != null) 121 { 122 int numChildren = children.getLength(); 123 124 for (int i = 0; i < numChildren; i++) 125 { 126 print(children.item(i), namespaceStack, out); 127 } 128 } 129 break; 130 } 131 132 case Node.ELEMENT_NODE : 133 { 134 namespaceStack = new ObjectRegistry(namespaceStack); 135 136 out.print('<' + node.getNodeName()); 137 138 String elPrefix = node.getPrefix(); 139 String elNamespaceURI = node.getNamespaceURI(); 140 141 if (elPrefix != null && elNamespaceURI != null) 142 { 143 boolean prefixIsDeclared = false; 144 145 try 146 { 147 String namespaceURI = (String )namespaceStack.lookup(elPrefix); 148 149 if (elNamespaceURI.equals(namespaceURI)) 150 { 151 prefixIsDeclared = true; 152 } 153 } 154 catch (IllegalArgumentException e) 155 { 156 } 157 158 if (!prefixIsDeclared) 159 { 160 printNamespaceDecl(node, namespaceStack, out); 161 } 162 } 163 164 NamedNodeMap attrs = node.getAttributes(); 165 int len = (attrs != null) ? attrs.getLength() : 0; 166 167 for (int i = 0; i < len; i++) 168 { 169 Attr attr = (Attr)attrs.item(i); 170 171 out.print(' ' + attr.getNodeName() +"=\"" + 172 normalize(attr.getValue()) + '\"'); 173 174 String attrPrefix = attr.getPrefix(); 175 String attrNamespaceURI = attr.getNamespaceURI(); 176 177 if (attrPrefix != null && attrNamespaceURI != null) 178 { 179 boolean prefixIsDeclared = false; 180 181 try 182 { 183 String namespaceURI = (String )namespaceStack.lookup(attrPrefix); 184 185 if (attrNamespaceURI.equals(namespaceURI)) 186 { 187 prefixIsDeclared = true; 188 } 189 } 190 catch (IllegalArgumentException e) 191 { 192 } 193 194 if (!prefixIsDeclared) 195 { 196 printNamespaceDecl(attr, namespaceStack, out); 197 } 198 } 199 } 200 201 NodeList children = node.getChildNodes(); 202 203 if (children != null) 204 { 205 int numChildren = children.getLength(); 206 207 hasChildren = (numChildren > 0); 208 209 if (hasChildren) 210 { 211 out.print('>'); 212 } 213 214 for (int i = 0; i < numChildren; i++) 215 { 216 print(children.item(i), namespaceStack, out); 217 } 218 } 219 else 220 { 221 hasChildren = false; 222 } 223 224 if (!hasChildren) 225 { 226 out.print("/>"); 227 } 228 break; 229 } 230 231 case Node.ENTITY_REFERENCE_NODE : 232 { 233 out.print('&'); 234 out.print(node.getNodeName()); 235 out.print(';'); 236 break; 237 } 238 239 case Node.CDATA_SECTION_NODE : 240 { 241 out.print("<![CDATA["); 242 out.print(node.getNodeValue()); 243 out.print("]]>"); 244 break; 245 } 246 247 case Node.TEXT_NODE : 248 { 249 out.print(normalize(node.getNodeValue())); 250 break; 251 } 252 253 case Node.COMMENT_NODE : 254 { 255 out.print("<!--"); 256 out.print(node.getNodeValue()); 257 out.print("-->"); 258 break; 259 } 260 261 case Node.PROCESSING_INSTRUCTION_NODE : 262 { 263 out.print("<?"); 264 out.print(node.getNodeName()); 265 266 String data = node.getNodeValue(); 267 268 if (data != null && data.length() > 0) 269 { 270 out.print(' '); 271 out.print(data); 272 } 273 274 out.println("?>"); 275 break; 276 } 277 } 278 279 if (type == Node.ELEMENT_NODE && hasChildren == true) 280 { 281 out.print("</"); 282 out.print(node.getNodeName()); 283 out.print('>'); 284 hasChildren = false; 285 } 286 } 287 288 private static void printNamespaceDecl(Node node, 289 ObjectRegistry namespaceStack, 290 PrintWriter out) 291 { 292 switch (node.getNodeType()) 293 { 294 case Node.ATTRIBUTE_NODE : 295 { 296 printNamespaceDecl(((Attr)node).getOwnerElement(), node, 297 namespaceStack, out); 298 break; 299 } 300 301 case Node.ELEMENT_NODE : 302 { 303 printNamespaceDecl((Element)node, node, namespaceStack, out); 304 break; 305 } 306 } 307 } 308 309 private static void printNamespaceDecl(Element owner, Node node, 310 ObjectRegistry namespaceStack, 311 PrintWriter out) 312 { 313 String namespaceURI = node.getNamespaceURI(); 314 String prefix = node.getPrefix(); 315 316 if (!(namespaceURI.equals(NS_URI_XMLNS) && prefix.equals("xmlns"))) 317 { 318 if (DOMUtils.getAttributeNS(owner, NS_URI_XMLNS, prefix) == null) 319 { 320 out.print(" xmlns:" + prefix + "=\"" + namespaceURI + '\"'); 321 } 322 } 323 else 324 { 325 prefix = node.getLocalName(); 326 namespaceURI = node.getNodeValue(); 327 } 328 329 namespaceStack.register(prefix, namespaceURI); 330 } 331 332 private static String normalize(String s) 333 { 334 StringBuffer str = new StringBuffer (); 335 int len = (s != null) ? s.length() : 0; 336 337 for (int i = 0; i < len; i++) 338 { 339 char ch = s.charAt(i); 340 341 switch (ch) 342 { 343 case '<' : 344 { 345 str.append("<"); 346 break; 347 } 348 case '>' : 349 { 350 str.append(">"); 351 break; 352 } 353 case '&' : 354 { 355 str.append("&"); 356 break; 357 } 358 case '"' : 359 { 360 str.append("""); 361 break; 362 } 363 case '\n' : 364 { 365 if (i > 0) 366 { 367 char lastChar = str.charAt(str.length() - 1); 368 369 if (lastChar != '\r') 370 { 371 str.append(StringUtils.lineSeparator); 372 } 373 else 374 { 375 str.append('\n'); 376 } 377 } 378 else 379 { 380 str.append(StringUtils.lineSeparator); 381 } 382 break; 383 } 384 default : 385 { 386 str.append(ch); 387 } 388 } 389 } 390 391 return (str.toString()); 392 } 393 } 394 | Popular Tags |