001: /* XMLWriter.java NanoXML/Java
002: *
003: * $Revision: 1421 $
004: * $Date: 2006-03-12 09:32:32 -0700 (Sun, 12 Mar 2006) $
005: * $Name$
006: *
007: * This file is part of NanoXML 2 for Java.
008: * Copyright (C) 2001 Marc De Scheemaecker, All Rights Reserved.
009: *
010: * This software is provided 'as-is', without any express or implied warranty.
011: * In no event will the authors be held liable for any damages arising from the
012: * use of this software.
013: *
014: * Permission is granted to anyone to use this software for any purpose,
015: * including commercial applications, and to alter it and redistribute it
016: * freely, subject to the following restrictions:
017: *
018: * 1. The origin of this software must not be misrepresented; you must not
019: * claim that you wrote the original software. If you use this software in
020: * a product, an acknowledgment in the product documentation would be
021: * appreciated but is not required.
022: *
023: * 2. Altered source versions must be plainly marked as such, and must not be
024: * misrepresented as being the original software.
025: *
026: * 3. This notice may not be removed or altered from any source distribution.
027: */
028:
029: package net.n3.nanoxml;
030:
031: import java.io.IOException;
032: import java.io.OutputStream;
033: import java.io.PrintWriter;
034: import java.io.Writer;
035: import java.util.Enumeration;
036:
037: /**
038: * An XMLWriter writes XML data to a stream.
039: *
040: * @see net.n3.nanoxml.XMLElement
041: * @see java.io.Writer
042: *
043: * @author Marc De Scheemaecker
044: * @version $Name$, $Revision: 1421 $
045: */
046: public class XMLWriter {
047:
048: /**
049: * Where to write the output to.
050: */
051: private PrintWriter writer;
052:
053: /**
054: * Creates a new XML writer.
055: *
056: * @param writer where to write the output to.
057: */
058: public XMLWriter(Writer writer) {
059: if (writer instanceof PrintWriter) {
060: this .writer = (PrintWriter) writer;
061: } else {
062: this .writer = new PrintWriter(writer);
063: }
064: }
065:
066: /**
067: * Creates a new XML writer.
068: *
069: * @param stream where to write the output to.
070: */
071: public XMLWriter(OutputStream stream) {
072: this .writer = new PrintWriter(stream);
073: }
074:
075: /**
076: * Cleans up the object when it's destroyed.
077: */
078: protected void finalize() throws Throwable {
079: this .writer = null;
080: super .finalize();
081: }
082:
083: /**
084: * Writes an XML element.
085: *
086: * @param xml the non-null XML element to write.
087: */
088: public void write(XMLElement xml) throws IOException {
089: this .write(xml, true, 0);
090: }
091:
092: /**
093: * Writes an XML element.
094: *
095: * @param xml the non-null XML element to write.
096: * @param prettyPrint if spaces need to be inserted to make the output more readable
097: */
098: public void write(XMLElement xml, boolean prettyPrint)
099: throws IOException {
100: this .write(xml, prettyPrint, 0);
101: }
102:
103: /**
104: * Writes an XML element.
105: *
106: * @param xml the non-null XML element to write.
107: * @param prettyPrint if spaces need to be inserted to make the output more readable
108: * @param indent how many spaces to indent the element.
109: */
110: public void write(XMLElement xml, boolean prettyPrint, int indent)
111: throws IOException {
112: if (prettyPrint) {
113: for (int i = 0; i < indent; i++) {
114: this .writer.print(' ');
115: }
116: }
117:
118: if (xml.getName() == null) {
119: if (xml.getContent() != null) {
120: if (prettyPrint) {
121: this .writeEncoded(xml.getContent().trim());
122: writer.println();
123: } else {
124: this .writeEncoded(xml.getContent());
125: }
126: }
127: } else {
128: this .writer.print('<');
129: this .writer.print(xml.getName());
130: Enumeration enumeration = xml.enumerateAttributeNames();
131:
132: while (enumeration.hasMoreElements()) {
133: String key = (String) enumeration.nextElement();
134: String value = xml.getAttribute(key);
135: this .writer.print(" " + key + "=\"");
136: this .writeEncoded(value);
137: this .writer.print('"');
138: }
139:
140: if ((xml.getContent() != null)
141: && (xml.getContent().length() > 0)) {
142: writer.print('>');
143: this .writeEncoded(xml.getContent());
144: writer.print("</" + xml.getName() + '>');
145:
146: if (prettyPrint) {
147: writer.println();
148: }
149: } else if (xml.hasChildren()) {
150: writer.print('>');
151:
152: if (prettyPrint) {
153: writer.println();
154: }
155:
156: enumeration = xml.enumerateChildren();
157:
158: while (enumeration.hasMoreElements()) {
159: XMLElement child = (XMLElement) enumeration
160: .nextElement();
161: this .write(child, prettyPrint, indent + 4);
162: }
163:
164: if (prettyPrint) {
165: for (int i = 0; i < indent; i++) {
166: this .writer.print(' ');
167: }
168: }
169:
170: this .writer.print("</" + xml.getName() + ">");
171:
172: if (prettyPrint) {
173: writer.println();
174: }
175: } else {
176: this .writer.print("/>");
177:
178: if (prettyPrint) {
179: writer.println();
180: }
181: }
182: }
183:
184: this .writer.flush();
185: }
186:
187: /**
188: * Writes a string encoding reserved characters.
189: *
190: * @param str the string to write.
191: */
192: private void writeEncoded(String str) {
193: for (int i = 0; i < str.length(); i++) {
194: char c = str.charAt(i);
195:
196: switch (c) {
197: case 0x0D:
198: case 0x0A:
199: this .writer.print(c);
200: break;
201:
202: case '<':
203: this .writer.print("<");
204: break;
205:
206: case '>':
207: this .writer.print(">");
208: break;
209:
210: case '&':
211: this .writer.print("&");
212: break;
213:
214: case '\'':
215: this .writer.print("'");
216: break;
217:
218: case '"':
219: this .writer.print(""");
220: break;
221:
222: default:
223: if ((c < ' ') || (c > 0x7E)) {
224: this .writer.print("&#x");
225: this .writer.print(Integer.toString(c, 16));
226: this .writer.print(';');
227: } else {
228: this.writer.print(c);
229: }
230: }
231: }
232: }
233:
234: }
|