001: /*
002: * (C) Copyright 2002-2003, Andy Clark. All rights reserved.
003: *
004: * This file is distributed under an Apache style license. Please
005: * refer to the LICENSE file for specific details.
006: */
007:
008: package sample;
009:
010: import org.cyberneko.pull.XMLEvent;
011: import org.cyberneko.pull.XMLPullParser;
012: import org.cyberneko.pull.event.CharactersEvent;
013: import org.cyberneko.pull.event.CommentEvent;
014: import org.cyberneko.pull.event.DoctypeDeclEvent;
015: import org.cyberneko.pull.event.ElementEvent;
016: import org.cyberneko.pull.event.ProcessingInstructionEvent;
017: import org.cyberneko.pull.parsers.Xerces2;
018:
019: import java.io.IOException;
020: import java.io.OutputStreamWriter;
021: import java.io.PrintWriter;
022:
023: import org.apache.xerces.xni.XMLAttributes;
024: import org.apache.xerces.xni.XMLString;
025: import org.apache.xerces.xni.XNIException;
026: import org.apache.xerces.xni.parser.XMLInputSource;
027:
028: /**
029: * A simple writer program to show the use of the pull parsing API. This
030: * program serializes event objects back to XML syntax.
031: *
032: * @author Andy Clark
033: *
034: * @version $Id$
035: */
036: public class Writer {
037:
038: //
039: // Constructors
040: //
041:
042: /** This class cannot be constructed. */
043: private Writer() {
044: } // <init>()
045:
046: //
047: // Public static methods
048: //
049:
050: /**
051: * Writes a document's content to standard output.
052: *
053: * @param parser The pull parser to use.
054: * @param sysid The system id of the document to read.
055: */
056: public static void write(XMLPullParser parser, String sysid)
057: throws XNIException, IOException {
058:
059: // variables
060: PrintWriter out = new PrintWriter(new OutputStreamWriter(
061: System.out, "UTF8"), true);
062: boolean seenRootElement = false;
063: int elementDepth = 0;
064:
065: // initialize parser
066: XMLInputSource source = new XMLInputSource(null, sysid, null);
067: parser.setInputSource(source);
068:
069: // parse document
070: XMLEvent event;
071: while ((event = parser.nextEvent()) != null) {
072: switch (event.type) {
073: case XMLEvent.ELEMENT: {
074: ElementEvent elementEvent = (ElementEvent) event;
075: seenRootElement = true;
076: if (elementEvent.start) {
077: out.print('<');
078: elementDepth++;
079: out.print(elementEvent.element.rawname);
080: XMLAttributes attrs = elementEvent.attributes;
081: int attrCount = attrs != null ? attrs.getLength()
082: : 0;
083: for (int i = 0; i < attrCount; i++) {
084: out.print(' ');
085: out.print(attrs.getQName(i));
086: out.print("=\"");
087: String avalue = attrs.getValue(i);
088: int length = avalue.length();
089: for (int j = 0; j < length; j++) {
090: char c = avalue.charAt(j);
091: switch (c) {
092: case '<': {
093: out.print("<");
094: break;
095: }
096: case '"': {
097: out.print(""");
098: break;
099: }
100: default: {
101: out.print(c);
102: }
103: }
104: }
105: out.print('"');
106: }
107: if (elementEvent.empty) {
108: elementDepth--;
109: out.print('/');
110: }
111: out.print('>');
112: out.flush();
113: } else if (!elementEvent.empty) {
114: elementDepth--;
115: out.print("</");
116: out.print(elementEvent.element.rawname);
117: out.print('>');
118: out.flush();
119: }
120: break;
121: }
122: case XMLEvent.CHARACTERS: {
123: CharactersEvent charactersEvent = (CharactersEvent) event;
124: XMLString text = charactersEvent.text;
125: for (int i = 0; i < text.length; i++) {
126: char c = text.ch[text.offset + i];
127: switch (c) {
128: case '<': {
129: out.print("<");
130: break;
131: }
132: case '>': {
133: out.print(">");
134: break;
135: }
136: case '&': {
137: out.print("&");
138: break;
139: }
140: default: {
141: out.print(c);
142: }
143: }
144: }
145: out.flush();
146: break;
147: }
148: case XMLEvent.COMMENT: {
149: CommentEvent commentEvent = (CommentEvent) event;
150: if (seenRootElement && elementDepth == 0) {
151: out.println();
152: }
153: out.print("<!--");
154: XMLString text = commentEvent.text;
155: for (int i = 0; i < text.length; i++) {
156: out.print(text.ch[text.offset + i]);
157: }
158: out.print("-->");
159: if (!seenRootElement) {
160: out.println();
161: }
162: out.flush();
163: break;
164: }
165: case XMLEvent.PROCESSING_INSTRUCTION: {
166: ProcessingInstructionEvent piEvent = (ProcessingInstructionEvent) event;
167: if (seenRootElement && elementDepth == 0) {
168: out.println();
169: }
170: out.print("<?");
171: out.print(piEvent.target);
172: if (piEvent.data != null) {
173: out.print(' ');
174: XMLString data = piEvent.data;
175: for (int i = 0; i < data.length; i++) {
176: out.print(data.ch[data.offset + i]);
177: }
178: }
179: out.print("?>");
180: if (!seenRootElement) {
181: out.println();
182: }
183: out.flush();
184: break;
185: }
186: case XMLEvent.DOCTYPE_DECL: {
187: DoctypeDeclEvent doctypeEvent = (DoctypeDeclEvent) event;
188: out.print("<!DOCTYPE ");
189: out.print(doctypeEvent.root);
190: out.print(' ');
191: if (doctypeEvent.pubid != null) {
192: out.print("PUBLIC \"");
193: out.print(doctypeEvent.pubid);
194: out.print("\" \"");
195: } else {
196: out.print("SYSTEM \"");
197: }
198: out.print(doctypeEvent.sysid);
199: out.print('"');
200: out.print('>');
201: out.println();
202: out.flush();
203: break;
204: }
205: }
206: }
207:
208: } // write(XMLPullParser,String)
209:
210: //
211: // MAIN
212: //
213:
214: /** Main program. */
215: public static void main(String[] argv) throws Exception {
216: XMLPullParser parser = new Xerces2();
217: for (int i = 0; i < argv.length; i++) {
218: Writer.write(parser, argv[i]);
219: }
220: } // main(String[])
221:
222: } // class Writer
|