1 16 17 package com.lowagie.text.xml; 18 19 import java.io.OutputStream ; 20 import java.io.OutputStreamWriter ; 21 import java.io.PrintWriter ; 22 import java.io.UnsupportedEncodingException ; 23 24 import org.w3c.dom.Attr ; 25 import org.w3c.dom.Document ; 26 import org.w3c.dom.DocumentType ; 27 import org.w3c.dom.NamedNodeMap ; 28 import org.w3c.dom.Node ; 29 30 34 public class XmlDomWriter { 35 36 37 protected PrintWriter fOut; 38 39 40 protected boolean fCanonical; 41 42 43 protected boolean fXML11; 44 45 49 50 public XmlDomWriter() { 51 } 53 public XmlDomWriter(boolean canonical) { 54 fCanonical = canonical; 55 } 57 61 62 public void setCanonical(boolean canonical) { 63 fCanonical = canonical; 64 } 66 67 public void setOutput(OutputStream stream, String encoding) 68 throws UnsupportedEncodingException { 69 70 if (encoding == null) { 71 encoding = "UTF8"; 72 } 73 74 java.io.Writer writer = new OutputStreamWriter (stream, encoding); 75 fOut = new PrintWriter (writer); 76 77 } 79 80 public void setOutput(java.io.Writer writer) { 81 82 fOut = writer instanceof PrintWriter 83 ? (PrintWriter )writer : new PrintWriter (writer); 84 85 } 87 88 public void write(Node node) { 89 90 if (node == null) { 92 return; 93 } 94 95 short type = node.getNodeType(); 96 switch (type) { 97 case Node.DOCUMENT_NODE: { 98 Document document = (Document )node; 99 fXML11 = false; if (!fCanonical) { 101 if (fXML11) { 102 fOut.println("<?xml version=\"1.1\" encoding=\"UTF-8\"?>"); 103 } else { 104 fOut.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); 105 } 106 fOut.flush(); 107 write(document.getDoctype()); 108 } 109 write(document.getDocumentElement()); 110 break; 111 } 112 113 case Node.DOCUMENT_TYPE_NODE: { 114 DocumentType doctype = (DocumentType )node; 115 fOut.print("<!DOCTYPE "); 116 fOut.print(doctype.getName()); 117 String publicId = doctype.getPublicId(); 118 String systemId = doctype.getSystemId(); 119 if (publicId != null) { 120 fOut.print(" PUBLIC '"); 121 fOut.print(publicId); 122 fOut.print("' '"); 123 fOut.print(systemId); 124 fOut.print('\''); 125 } else if (systemId != null) { 126 fOut.print(" SYSTEM '"); 127 fOut.print(systemId); 128 fOut.print('\''); 129 } 130 String internalSubset = doctype.getInternalSubset(); 131 if (internalSubset != null) { 132 fOut.println(" ["); 133 fOut.print(internalSubset); 134 fOut.print(']'); 135 } 136 fOut.println('>'); 137 break; 138 } 139 140 case Node.ELEMENT_NODE: { 141 fOut.print('<'); 142 fOut.print(node.getNodeName()); 143 Attr attrs[] = sortAttributes(node.getAttributes()); 144 for (int i = 0; i < attrs.length; i++) { 145 Attr attr = attrs[i]; 146 fOut.print(' '); 147 fOut.print(attr.getNodeName()); 148 fOut.print("=\""); 149 normalizeAndPrint(attr.getNodeValue(), true); 150 fOut.print('"'); 151 } 152 fOut.print('>'); 153 fOut.flush(); 154 155 Node child = node.getFirstChild(); 156 while (child != null) { 157 write(child); 158 child = child.getNextSibling(); 159 } 160 break; 161 } 162 163 case Node.ENTITY_REFERENCE_NODE: { 164 if (fCanonical) { 165 Node child = node.getFirstChild(); 166 while (child != null) { 167 write(child); 168 child = child.getNextSibling(); 169 } 170 } else { 171 fOut.print('&'); 172 fOut.print(node.getNodeName()); 173 fOut.print(';'); 174 fOut.flush(); 175 } 176 break; 177 } 178 179 case Node.CDATA_SECTION_NODE: { 180 if (fCanonical) { 181 normalizeAndPrint(node.getNodeValue(), false); 182 } else { 183 fOut.print("<![CDATA["); 184 fOut.print(node.getNodeValue()); 185 fOut.print("]]>"); 186 } 187 fOut.flush(); 188 break; 189 } 190 191 case Node.TEXT_NODE: { 192 normalizeAndPrint(node.getNodeValue(), false); 193 fOut.flush(); 194 break; 195 } 196 197 case Node.PROCESSING_INSTRUCTION_NODE: { 198 fOut.print("<?"); 199 fOut.print(node.getNodeName()); 200 String data = node.getNodeValue(); 201 if (data != null && data.length() > 0) { 202 fOut.print(' '); 203 fOut.print(data); 204 } 205 fOut.print("?>"); 206 fOut.flush(); 207 break; 208 } 209 210 case Node.COMMENT_NODE: { 211 if (!fCanonical) { 212 fOut.print("<!--"); 213 String comment = node.getNodeValue(); 214 if (comment != null && comment.length() > 0) { 215 fOut.print(comment); 216 } 217 fOut.print("-->"); 218 fOut.flush(); 219 } 220 } 221 } 222 223 if (type == Node.ELEMENT_NODE) { 224 fOut.print("</"); 225 fOut.print(node.getNodeName()); 226 fOut.print('>'); 227 fOut.flush(); 228 } 229 230 } 232 233 protected Attr [] sortAttributes(NamedNodeMap attrs) { 234 235 int len = (attrs != null) ? attrs.getLength() : 0; 236 Attr array[] = new Attr [len]; 237 for (int i = 0; i < len; i++) { 238 array[i] = (Attr )attrs.item(i); 239 } 240 for (int i = 0; i < len - 1; i++) { 241 String name = array[i].getNodeName(); 242 int index = i; 243 for (int j = i + 1; j < len; j++) { 244 String curName = array[j].getNodeName(); 245 if (curName.compareTo(name) < 0) { 246 name = curName; 247 index = j; 248 } 249 } 250 if (index != i) { 251 Attr temp = array[i]; 252 array[i] = array[index]; 253 array[index] = temp; 254 } 255 } 256 257 return array; 258 259 } 261 265 266 protected void normalizeAndPrint(String s, boolean isAttValue) { 267 268 int len = (s != null) ? s.length() : 0; 269 for (int i = 0; i < len; i++) { 270 char c = s.charAt(i); 271 normalizeAndPrint(c, isAttValue); 272 } 273 274 } 276 277 protected void normalizeAndPrint(char c, boolean isAttValue) { 278 279 switch (c) { 280 case '<': { 281 fOut.print("<"); 282 break; 283 } 284 case '>': { 285 fOut.print(">"); 286 break; 287 } 288 case '&': { 289 fOut.print("&"); 290 break; 291 } 292 case '"': { 293 if (isAttValue) { 296 fOut.print("""); 297 } else { 298 fOut.print("\""); 299 } 300 break; 301 } 302 case '\r': { 303 fOut.print("
"); 308 break; 309 } 310 case '\n': { 311 if (fCanonical) { 312 fOut.print("
"); 313 break; 314 } 315 } 317 default: { 318 if (fXML11 && ((c >= 0x01 && c <= 0x1F && c != 0x09 && c != 0x0A) 327 || (c >= 0x7F && c <= 0x9F) || c == 0x2028) 328 || isAttValue && (c == 0x09 || c == 0x0A)) { 329 fOut.print("&#x"); 330 fOut.print(Integer.toHexString(c).toUpperCase()); 331 fOut.print(";"); 332 } else { 333 fOut.print(c); 334 } 335 } 336 } 337 } 339 340 } 359 | Popular Tags |