XmlWriter.java
上传用户:haojie1228
上传日期:2022-08-08
资源大小:347k
文件大小:5k
源码类别:

通讯/手机编程

开发平台:

Java

  1. /* kXML
  2.  *
  3.  * The contents of this file are subject to the Enhydra Public License
  4.  * Version 1.1 (the "License"); you may not use this file except in
  5.  * compliance with the License. You may obtain a copy of the License
  6.  * on the Enhydra web site ( http://www.enhydra.org/ ).
  7.  *
  8.  * Software distributed under the License is distributed on an "AS IS"
  9.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  10.  * the License for the specific terms governing rights and limitations
  11.  * under the License.
  12.  *
  13.  * The Initial Developer of kXML is Stefan Haustein. Copyright (C)
  14.  * 2000, 2001 Stefan Haustein, D-46045 Oberhausen (Rhld.),
  15.  * Germany. All Rights Reserved.
  16.  *
  17.  * Contributor(s): Paul Palaszewski, Wilhelm Fitzpatrick, 
  18.  *                 Eric Foster-Johnson, Hans-Harald Schulz
  19.  *
  20.  * */
  21. package org.kxml.io;
  22. import java.io.*;
  23. import java.util.*;
  24. import org.kxml.*;
  25. /** a concrete XML Writer */
  26. public class XmlWriter extends AbstractXmlWriter {
  27.     protected Writer writer;
  28.     boolean pending = false;
  29.     int indentLevel = 0;
  30.     int noIndent = Integer.MAX_VALUE;
  31.     static char [] indent 
  32. = {'r', 'n', ' ', ' ', ' ', ' ', ' ', ' ', 
  33.    ' ', ' ', ' ', ' ', ' ', ' ',  ' ', ' '};
  34.     
  35.     /** creates a new xmlWritet based on the given writer */
  36.     
  37.     public XmlWriter (Writer writer) {
  38. this.writer = writer;
  39.     }
  40.     
  41.     protected void checkPending () throws IOException {
  42. if (pending) {
  43.     writer.write ('>');
  44.     pending = false;
  45. }
  46.     }
  47.     /** closes the XmlWriter by closing the underlying writer */
  48.     public void close () throws IOException {
  49. flush ();
  50. writer.close ();
  51.     }
  52.     /** flushes the XmlWriter. Attention: If a closing
  53. angle braket is pending, it will be appended before
  54. flushing the underlying writer. Thus, after flush
  55. attributes cannot be added any longer */
  56.     public void flush () throws IOException {
  57. checkPending ();
  58. writer.flush ();
  59.     }
  60.     /** writes a single character using the xml escaping rules */
  61.     public void write (char c) throws IOException {
  62. checkPending ();
  63. if (noIndent > indentLevel) noIndent = indentLevel;
  64. switch (c) {
  65. case '<': writer.write ("&lt;"); break;
  66. case '>': writer.write ("&gt;"); break;
  67. case '&': writer.write ("&amp;"); break;   
  68. default: writer.write (c); 
  69. }  
  70.     }
  71.     
  72.     
  73.     /** writes an character array using the XML escaping rules */
  74.     public void write (char [] buf, int start, int len) throws IOException {
  75. checkPending ();
  76. if (noIndent > indentLevel) noIndent = indentLevel;
  77. int end = start + len;
  78. do {
  79.     int i = start;
  80.     
  81.     while (i < end && "<>&".indexOf (buf [i]) == -1) i++; 
  82.     
  83.     writer.write (buf, start, i - start);
  84.     
  85.     if (i == end) break;
  86.     
  87.     write (buf [i]);
  88.     start = i+1;
  89. }   
  90. while (start < end);
  91.     }
  92.     
  93.     public void writeIndent () throws IOException {
  94. int l = indentLevel + 2;
  95. if (l < 2) l = 2;
  96. else if (l > indent.length) l = indent.length;
  97. checkPending ();
  98. // writer.write ("<!-- i -->");
  99. writer.write (indent, 0, l);
  100.     }
  101.     /** writes a degenerated tag with the given name and attributes */
  102.     public void attribute (String name, 
  103.    String value) throws IOException {
  104. if (!pending) throw new RuntimeException 
  105.     ("can write attr only immediately after a startTag");
  106. writer.write (' ');
  107. writer.write (name);
  108. writer.write ("="");
  109. writer.write (Xml.encode (value, Xml.ENCODE_QUOT));
  110. writer.write ('"');
  111. if (name.equals ("xml:space") && value.equals ("preserve"))
  112.     noIndent = indentLevel;
  113.     }
  114.     /** writes a start tag with the given name */
  115.     protected void startTag (PrefixMap prefixMap, 
  116.      String tag) throws IOException {
  117. current = new State (current, prefixMap, tag);
  118. checkPending ();
  119. if (indentLevel < noIndent) 
  120.     writeIndent ();
  121. indentLevel++;
  122. writer.write ('<');
  123. writer.write (tag);
  124. pending = true;
  125.     }
  126.     
  127.     /** writes an end tag. */
  128.     public void endTag () throws IOException {
  129. indentLevel--;
  130. if (pending) {
  131.     writer.write (" />");
  132.     pending = false;
  133. }
  134. else {
  135.     if (indentLevel + 1 < noIndent) 
  136. writeIndent ();
  137.     writer.write ("</");
  138.     writer.write (current.tag);
  139.     writer.write (">");
  140. }
  141. if (indentLevel + 1 == noIndent) 
  142.     noIndent = Integer.MAX_VALUE;
  143. current = current.prev;
  144. if (current == null) 
  145.     throw new RuntimeException ("too many closing tags!");
  146.     }   
  147.     /** ATTENTION: Application needs to take care about not writing
  148.         illegal character sequences (like comment end in comments) */
  149.     public void writeLegacy (int type, String content) throws IOException {
  150. checkPending ();
  151. switch (type) {
  152. case Xml.COMMENT: 
  153.     writer.write ("<!--");
  154.     writer.write (content);
  155.     writer.write ("-->");
  156.     break;
  157. case Xml.DOCTYPE:
  158.     writer.write ("<!DOCTYPE ");
  159.     writer.write (content);
  160.     writer.write (">");
  161.     break;
  162. case Xml.PROCESSING_INSTRUCTION:
  163.     writer.write ("<?");
  164.     writer.write (content);
  165.     writer.write ("?>");
  166.     break;
  167. }
  168.     }
  169.     /** writes a string without escaping. Use with care! Not
  170. available in wbxml writer */
  171.     public void writeRaw (String s) throws IOException {
  172. checkPending ();
  173. writer.write (s);
  174.     }
  175. }