1 19 20 21 package org.openharmonise.commons.xml; 22 23 import java.io.*; 24 import java.util.*; 25 import java.util.logging.*; 26 27 import org.openharmonise.commons.xml.namespace.*; 28 import org.w3c.dom.*; 29 30 37 38 public class XMLPrettyPrint { 39 40 43 private NamespaceResolver m_resolver = null; 44 45 48 private boolean m_bNamespaceAware = false; 49 50 53 private static final Logger m_logger = Logger.getLogger(XMLPrettyPrint.class.getName()); 54 55 public XMLPrettyPrint() { 56 } 57 58 66 public void setNamespaceAware(boolean bNamespaceAware) { 67 this.m_bNamespaceAware = bNamespaceAware; 68 if( bNamespaceAware && m_resolver==null ) { 69 m_resolver = new LocalNamespaceResolver(); 70 } 71 } 72 73 78 public boolean isNamespaceAware() { 79 return this.m_bNamespaceAware; 80 } 81 82 91 public void setNamespaceResolver(NamespaceResolver resolver) { 92 if (resolver != null) { 93 this.m_resolver = resolver; 94 this.m_bNamespaceAware = true; 95 } else { 96 this.m_resolver = null; 97 this.m_bNamespaceAware = false; 98 } 99 } 100 101 106 public NamespaceResolver getNamespaceResolver() { 107 return this.m_resolver; 108 } 109 110 116 public void printNodeToFile(Node node, String sFilepath) { 117 printNodeToFile(node, new File(sFilepath)); 118 } 119 120 126 public void printNodeToFile(Node node, File file) { 127 try { 128 FileOutputStream fos = new FileOutputStream(file); 129 OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); 130 131 osw.write(printNode(node)); 132 133 osw.close(); 134 fos.close(); 135 } catch (Exception e) { 136 m_logger.log(Level.WARNING, e.getMessage(), e); 137 } 138 } 139 140 146 public String printNode(Document doc) throws NamespaceClashException { 147 StringBuffer sBuff = new StringBuffer ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 148 149 List aInScopeNamespaces = new ArrayList(); 150 151 int nChildren = doc.getChildNodes().getLength(); 152 153 if (nChildren == 1) { 154 Node firstNode = doc.getFirstChild(); 155 156 if (firstNode.getNodeType() == Node.TEXT_NODE 157 && ((Text) firstNode).getNodeValue().equals("")) { 158 159 } else if (firstNode.getNodeType() == Node.TEXT_NODE) { 160 sBuff.append(((Text) firstNode).getData()); 161 162 } else { 163 printNode(firstNode, 1, sBuff, (List)((ArrayList)aInScopeNamespaces).clone()); 164 } 165 } else { 166 NodeList nl = doc.getChildNodes(); 167 168 for (int i = 0; i < nl.getLength(); i++) { 169 printNode(nl.item(i), 1, sBuff, (List)((ArrayList)aInScopeNamespaces).clone()); 170 } 171 } 172 173 return sBuff.toString(); 174 } 175 176 183 public String printNode(Node node) throws NamespaceClashException { 184 return printNode(node,true); 185 } 186 187 195 public String printNode(Node node, boolean includeXMLDeclaration) throws NamespaceClashException { 196 StringBuffer sBuff = new StringBuffer (); 197 if(includeXMLDeclaration){ 198 sBuff.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 199 } 200 201 List aInScopeNamespaces = new ArrayList(); 202 203 if( this.m_bNamespaceAware ) { 204 if( node.getNodeType()==Node.ELEMENT_NODE && ((Element)node).hasAttribute("xmlns")) { 205 this.m_resolver.addNamespace( ((Element)node).getAttribute("xmlns"), "" ); 206 } 207 } 208 209 if (node instanceof Text) { 210 printTextNode((Text) node, sBuff); 211 } else if(node instanceof Comment) { 212 printComment((Comment) node, 0, sBuff); 213 } else { 214 sBuff.append("<").append( this.handleElementName(node, aInScopeNamespaces) ); 215 216 if (node instanceof Element) { 217 printAttributes((Element) node, sBuff, aInScopeNamespaces); 218 } 219 int nChildren = node.getChildNodes().getLength(); 220 if (nChildren == 0) { 221 sBuff.append("/>"); 222 return sBuff.toString(); 223 } else if (nChildren == 1) { 224 Node firstNode = node.getFirstChild(); 225 if (firstNode.getNodeType() == Node.TEXT_NODE 226 && ((Text) firstNode).getNodeValue().equals("")) { 227 sBuff.append("/>"); 228 } else if (firstNode.getNodeType() == Node.TEXT_NODE) { 229 sBuff 230 .append(">") 231 .append(((Text) firstNode).getData()) 232 .append("</") 233 .append(node.getNodeName()) 234 .append(">"); 235 } else { 236 sBuff.append(">\n"); 237 printNode(firstNode, 1, sBuff, (List)((ArrayList)aInScopeNamespaces).clone()); 238 sBuff.append("\n</").append( this.handleElementName(node, aInScopeNamespaces) ).append(">"); 239 } 240 } else { 241 NodeList nl = node.getChildNodes(); 242 sBuff.append(">\n"); 243 for (int i = 0; i < nl.getLength(); i++) { 244 printNode(nl.item(i), 1, sBuff, (List)((ArrayList)aInScopeNamespaces).clone()); 245 } 246 sBuff.append("</").append( this.handleElementName(node, aInScopeNamespaces) ).append(">"); 247 } 248 } 249 return sBuff.toString(); 250 } 251 252 261 private void printNode(Node node, int nLevel, StringBuffer sBuff, List aInScopeNamespaces) throws NamespaceClashException { 262 if (node.getNodeType() == Node.ELEMENT_NODE) { 263 printElementNode((Element) node, nLevel + 1, sBuff, aInScopeNamespaces); 264 } else if (node.getNodeType() == Node.CDATA_SECTION_NODE) { 265 printCDATA((CDATASection) node, nLevel + 1, sBuff); 266 } else if (node.getNodeType() == Node.TEXT_NODE) { 267 printTextNode((Text) node, sBuff); 268 } else if(node.getNodeType() == Node.COMMENT_NODE) { 269 printComment((Comment) node, nLevel, sBuff); 270 } 271 } 272 273 282 private void printElementNode(Element el, int nLevel, StringBuffer sBuff, List aInScopeNamespaces) throws NamespaceClashException { 283 NodeList nl = el.getChildNodes(); 284 int nChildren = nl.getLength(); 285 if (nChildren == 0) { 286 printElementSelfClosing(el, nLevel, true, sBuff, aInScopeNamespaces); 287 sBuff.append("\n"); 288 } else if (nChildren == 1) { 289 Node firstnode = el.getFirstChild(); 290 if (firstnode.getNodeType() == Node.TEXT_NODE 291 && (((Text) firstnode).getNodeValue() == null 292 || ((Text) firstnode).getNodeValue().equals(""))) { 293 printElementSelfClosing(el, nLevel, true, sBuff, (List)((ArrayList)aInScopeNamespaces).clone()); 294 sBuff.append("\n"); 295 } else if (firstnode.getNodeType() == Node.TEXT_NODE) { 296 List newInScopeNamespaces = (List)((ArrayList)aInScopeNamespaces).clone(); 297 printElementStart(el, nLevel, true, sBuff, newInScopeNamespaces); 298 printNode(firstnode, nLevel, sBuff, newInScopeNamespaces); 299 printElementEnd(el, nLevel, false, sBuff, newInScopeNamespaces); 300 sBuff.append("\n"); 301 } else { 302 List newInScopeNamespaces = (List)((ArrayList)aInScopeNamespaces).clone(); 303 printElementStart(el, nLevel, true, sBuff, newInScopeNamespaces); 304 sBuff.append("\n"); 305 printNode(firstnode, nLevel + 1, sBuff, newInScopeNamespaces); 306 printElementEnd(el, nLevel, true, sBuff, newInScopeNamespaces); 307 sBuff.append("\n"); 308 } 309 } else { 310 printElementStart(el, nLevel, true, sBuff, aInScopeNamespaces); 311 sBuff.append("\n"); 312 for (int i = 0; i < nChildren; i++) { 313 Node node = nl.item(i); 314 printNode(node, nLevel + 1, sBuff, (List)((ArrayList)aInScopeNamespaces).clone()); 315 } 316 printElementEnd(el, nLevel, true, sBuff, aInScopeNamespaces); 317 sBuff.append("\n"); 318 } 319 } 320 321 331 private void printElementStart( 332 Element el, 333 int nLevel, 334 boolean bTabs, 335 StringBuffer sBuff, List aInScopeNamespaces) throws NamespaceClashException { 336 if (bTabs) { 337 printTabs(nLevel, sBuff); 338 } 339 sBuff.append("<").append( this.handleElementName(el, aInScopeNamespaces) ); 340 printAttributes(el, sBuff, aInScopeNamespaces); 341 sBuff.append(">"); 342 } 343 344 354 private void printElementEnd( 355 Element el, 356 int nLevel, 357 boolean bTabs, 358 StringBuffer sBuff, List aInScopeNamespaces) throws NamespaceClashException { 359 if (bTabs) { 360 printTabs(nLevel, sBuff); 361 } 362 sBuff.append("</").append( this.handleElementName(el, aInScopeNamespaces) ).append(">"); 363 } 364 365 376 private void printElementSelfClosing( 377 Element el, 378 int nLevel, 379 boolean bTabs, 380 StringBuffer sBuff, List aInScopeNamespaces) throws NamespaceClashException { 381 if (bTabs) { 382 printTabs(nLevel, sBuff); 383 } 384 sBuff.append("<").append( this.handleElementName(el, aInScopeNamespaces) ); 385 printAttributes(el, sBuff, aInScopeNamespaces); 386 sBuff.append("/>"); 387 } 388 389 397 private void printAttributes(Element el, StringBuffer sBuff, List aInScopeNamespaces) throws NamespaceClashException { 398 NamedNodeMap attribs = el.getAttributes(); 399 for (int i = 0; i < attribs.getLength(); i++) { 400 Attr nextAtt = (Attr) attribs.item(i); 401 if( !this.m_bNamespaceAware || nextAtt.getNodeName().indexOf("xmlns")==-1 ) { 402 sBuff 403 .append(" ") 404 .append( this.handleAttributeName(nextAtt, aInScopeNamespaces) ) 405 .append("=\"") 406 .append(this.encodeXMLText(nextAtt.getValue())) 407 .append("\""); 408 } 409 } 410 } 411 412 418 private void printTextNode(Text txt, StringBuffer sBuff) { 419 sBuff.append(encodeXMLText(txt.getNodeValue().trim()).trim()); 420 } 421 422 431 private String handleElementName(Node node, List aInScopeNamespaces) throws NamespaceClashException { 432 String sReturn=""; 433 434 if( this.m_bNamespaceAware ) { 435 if( node.getLocalName()==null ) { 436 sReturn=node.getNodeName(); 437 } else { 438 if( node.getNamespaceURI()!=null ) { 439 String sPrefix = this.m_resolver.getPrefixByNode(node); 440 sReturn = sPrefix; 441 if( !sPrefix.equals("")){ 442 sReturn = sReturn + ":"; 443 } 444 sReturn = sReturn + node.getLocalName(); 445 if( !aInScopeNamespaces.contains(node.getNamespaceURI()) ) { 446 aInScopeNamespaces.add(node.getNamespaceURI()); 447 sReturn = sReturn + " xmlns"; 448 if( !sPrefix.equals("")){ 449 sReturn = sReturn + ":"; 450 } 451 sReturn = sReturn + sPrefix + "=\"" + node.getNamespaceURI() + "\""; 452 } 453 } else { 454 sReturn = node.getLocalName(); 455 } 456 } 457 } else { 458 if( node.getLocalName()==null ) { 459 sReturn=node.getNodeName(); 460 } else { 461 sReturn=node.getLocalName(); 462 } 463 } 464 465 return sReturn; 466 } 467 468 477 private String handleAttributeName(Node node, List aInScopeNamespaces) throws NamespaceClashException { 478 String sReturn=""; 479 480 if( this.m_bNamespaceAware ) { 481 if( node.getLocalName()==null ) { 482 sReturn=node.getNodeName(); 483 } else { 484 if( node.getNamespaceURI()!=null ) { 485 String sPrefix = this.m_resolver.getPrefixByNode(node); 486 if( !aInScopeNamespaces.contains(node.getNamespaceURI()) ) { 487 aInScopeNamespaces.add(node.getNamespaceURI()); 488 sReturn = "xmlns:" + sPrefix + "=\"" + node.getNamespaceURI() + "\" "; 489 } 490 sReturn = sReturn + sPrefix + ":" + node.getLocalName(); 491 } else { 492 sReturn = node.getLocalName(); 493 } 494 } 495 } else { 496 if( node.getLocalName()==null ) { 497 sReturn=node.getNodeName(); 498 } else { 499 sReturn=node.getLocalName(); 500 } 501 } 502 503 return sReturn; 504 } 505 506 512 public String encodeXMLText(String sText) { 513 StringBuffer sBuff2 = new StringBuffer (sText); 514 StringBuffer sNewBuff = new StringBuffer (); 515 516 for (int i = 0; i < sBuff2.length(); i++) { 517 char currChar = sBuff2.charAt(i); 518 Character currCharObj = new Character (sBuff2.charAt(i)); 519 if (currChar == '&') { 520 if ((sBuff2.length() - 1 - i) >= 4 521 && sBuff2.charAt(i + 1) == 'a' 522 && sBuff2.charAt(i + 2) == 'm' 523 && sBuff2.charAt(i + 3) == 'p' 524 && sBuff2.charAt(i + 4) == ';') { 525 i = i + 4; 526 sNewBuff.append("&"); 527 } else { 528 sNewBuff.append("&"); 529 } 530 } else if (currChar == '>') { 531 sNewBuff.append(">"); 532 } else if (currChar == '<') { 533 sNewBuff.append("<"); 534 } else { 535 sNewBuff.append(currChar); 536 } 537 } 538 539 return sNewBuff.toString(); 540 } 541 542 548 public String decodeXMLText(String sText) { 549 StringBuffer sBuff2 = new StringBuffer (sText); 550 StringBuffer sNewBuff = new StringBuffer (); 551 552 for (int i = 0; i < sBuff2.length(); i++) { 553 char currChar = sBuff2.charAt(i); 554 Character currCharObj = new Character (sBuff2.charAt(i)); 555 if (currChar == '&') { 556 if (sBuff2.charAt(i + 1) == 'a' 557 && sBuff2.charAt(i + 2) == 'm' 558 && sBuff2.charAt(i + 3) == 'p' 559 && sBuff2.charAt(i + 4) == ';' 560 && sBuff2.charAt(i + 5) == 'a' 561 && sBuff2.charAt(i + 6) == 'm' 562 && sBuff2.charAt(i + 7) == 'p' 563 && sBuff2.charAt(i + 8) == ';') { 564 i = i + 8; 565 sNewBuff.append("&"); 566 } else if ( 567 sBuff2.charAt(i + 1) == 'a' 568 && sBuff2.charAt(i + 2) == 'm' 569 && sBuff2.charAt(i + 3) == 'p' 570 && sBuff2.charAt(i + 4) == ';') { 571 i = i + 4; 572 sNewBuff.append("&"); 573 } else if (currChar == '£') { 574 System.out.println("Decoding pound"); 575 sNewBuff.append("£"); 576 } else { 577 sNewBuff.append("&"); 578 } 579 } else { 580 sNewBuff.append(currChar); 581 } 582 } 583 584 return sNewBuff.toString(); 585 } 586 587 594 private void printCDATA( 595 CDATASection cdata, 596 int nLevel, 597 StringBuffer sBuff) { 598 printTabs(nLevel, sBuff); 599 sBuff.append("<![CDATA[").append(cdata.getData()).append("]]>\n"); 600 } 601 602 609 private void printComment( 610 Comment comment, 611 int nLevel, 612 StringBuffer sBuff) { 613 printTabs(nLevel, sBuff); 614 sBuff.append("<!--").append(comment.getData()).append("-->\n"); 615 } 616 617 623 private void printTabs(int nLevel, StringBuffer sBuff) { 624 for (int i = 0; i < nLevel; i++) { 625 sBuff.append(" "); 626 } 627 } 628 629 } | Popular Tags |