Mega Code Archive

 
Categories / Java / XML
 

XML Document Writer

/*  * Copyright (c) 2000 David Flanagan.  All rights reserved.  * This code is from the book Java Examples in a Nutshell, 2nd Edition.  * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.  * You may study, use, and modify it for any non-commercial purpose.  * You may distribute it non-commercially as long as you retain this notice.  * For a commercial use license, or to purchase the book (recommended),  * visit http://www.davidflanagan.com/javaexamples2.  */ import java.io.PrintWriter; import org.w3c.dom.CDATASection; import org.w3c.dom.Comment; import org.w3c.dom.Document; import org.w3c.dom.DocumentType; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.ProcessingInstruction; import org.w3c.dom.Text; /**  * Output a DOM Level 1 Document object to a java.io.PrintWriter as a simple XML  * document. This class does not handle every type of DOM node, and it doesn't  * deal with all the details of XML like DTDs, character encodings and preserved  * and ignored whitespace. However, it does output basic well-formed XML that  * can be parsed by a non-validating parser.  */ public class XMLDocumentWriter {   PrintWriter out; // the stream to send output to   /** Initialize the output stream */   public XMLDocumentWriter(PrintWriter out) {     this.out = out;   }   /** Close the output stream. */   public void close() {     out.close();   }   /** Output a DOM Node (such as a Document) to the output stream */   public void write(Node node) {     write(node, "");   }   /**    * Output the specified DOM Node object, printing it using the specified    * indentation string    */   public void write(Node node, String indent) {     // The output depends on the type of the node     switch (node.getNodeType()) {     case Node.DOCUMENT_NODE: { // If its a Document node       Document doc = (Document) node;       out.println(indent + "<?xml version='1.0'?>"); // Output header       Node child = doc.getFirstChild(); // Get the first node       while (child != null) { // Loop 'till no more nodes         write(child, indent); // Output node         child = child.getNextSibling(); // Get next node       }       break;     }     case Node.DOCUMENT_TYPE_NODE: { // It is a <!DOCTYPE> tag       DocumentType doctype = (DocumentType) node;       // Note that the DOM Level 1 does not give us information about       // the the public or system ids of the doctype, so we can't output       // a complete <!DOCTYPE> tag here. We can do better with Level 2.       out.println("<!DOCTYPE " + doctype.getName() + ">");       break;     }     case Node.ELEMENT_NODE: { // Most nodes are Elements       Element elt = (Element) node;       out.print(indent + "<" + elt.getTagName()); // Begin start tag       NamedNodeMap attrs = elt.getAttributes(); // Get attributes       for (int i = 0; i < attrs.getLength(); i++) { // Loop through them         Node a = attrs.item(i);         out.print(" " + a.getNodeName() + "='" + // Print attr. name             fixup(a.getNodeValue()) + "'"); // Print attr. value       }       out.println(">"); // Finish start tag       String newindent = indent + "    "; // Increase indent       Node child = elt.getFirstChild(); // Get child       while (child != null) { // Loop         write(child, newindent); // Output child         child = child.getNextSibling(); // Get next child       }       out.println(indent + "</" + // Output end tag           elt.getTagName() + ">");       break;     }     case Node.TEXT_NODE: { // Plain text node       Text textNode = (Text) node;       String text = textNode.getData().trim(); // Strip off space       if ((text != null) && text.length() > 0) // If non-empty         out.println(indent + fixup(text)); // print text       break;     }     case Node.PROCESSING_INSTRUCTION_NODE: { // Handle PI nodes       ProcessingInstruction pi = (ProcessingInstruction) node;       out.println(indent + "<?" + pi.getTarget() + " " + pi.getData()           + "?>");       break;     }     case Node.ENTITY_REFERENCE_NODE: { // Handle entities       out.println(indent + "&" + node.getNodeName() + ";");       break;     }     case Node.CDATA_SECTION_NODE: { // Output CDATA sections       CDATASection cdata = (CDATASection) node;       // Careful! Don't put a CDATA section in the program itself!       out.println(indent + "<" + "![CDATA[" + cdata.getData() + "]]"           + ">");       break;     }     case Node.COMMENT_NODE: { // Comments       Comment c = (Comment) node;       out.println(indent + "<!--" + c.getData() + "-->");       break;     }     default: // Hopefully, this won't happen too much!       System.err.println("Ignoring node: " + node.getClass().getName());       break;     }   }   // This method replaces reserved characters with entities.   String fixup(String s) {     StringBuffer sb = new StringBuffer();     int len = s.length();     for (int i = 0; i < len; i++) {       char c = s.charAt(i);       switch (c) {       default:         sb.append(c);         break;       case '<':         sb.append("&lt;");         break;       case '>':         sb.append("&gt;");         break;       case '&':         sb.append("&amp;");         break;       case '"':         sb.append("&quot;");         break;       case '\'':         sb.append("&apos;");         break;       }     }     return sb.toString();   } }