1 |
| |
2 |
| |
3 |
| |
4 |
| |
5 |
| |
6 |
| |
7 |
| |
8 |
| |
9 |
| |
10 |
| package org.dom4j.io; |
11 |
| |
12 |
| import java.io.BufferedWriter; |
13 |
| import java.io.IOException; |
14 |
| import java.io.OutputStream; |
15 |
| import java.io.OutputStreamWriter; |
16 |
| import java.io.UnsupportedEncodingException; |
17 |
| import java.io.Writer; |
18 |
| import java.util.HashMap; |
19 |
| import java.util.Iterator; |
20 |
| import java.util.List; |
21 |
| import java.util.Map; |
22 |
| import java.util.StringTokenizer; |
23 |
| |
24 |
| import org.dom4j.Attribute; |
25 |
| import org.dom4j.CDATA; |
26 |
| import org.dom4j.Comment; |
27 |
| import org.dom4j.Document; |
28 |
| import org.dom4j.DocumentType; |
29 |
| import org.dom4j.Element; |
30 |
| import org.dom4j.Entity; |
31 |
| import org.dom4j.Namespace; |
32 |
| import org.dom4j.Node; |
33 |
| import org.dom4j.ProcessingInstruction; |
34 |
| import org.dom4j.Text; |
35 |
| import org.dom4j.tree.NamespaceStack; |
36 |
| import org.xml.sax.Attributes; |
37 |
| import org.xml.sax.InputSource; |
38 |
| import org.xml.sax.Locator; |
39 |
| import org.xml.sax.SAXException; |
40 |
| import org.xml.sax.SAXNotRecognizedException; |
41 |
| import org.xml.sax.SAXNotSupportedException; |
42 |
| import org.xml.sax.XMLReader; |
43 |
| import org.xml.sax.ext.LexicalHandler; |
44 |
| import org.xml.sax.helpers.XMLFilterImpl; |
45 |
| |
46 |
| |
47 |
| |
48 |
| |
49 |
| |
50 |
| |
51 |
| |
52 |
| |
53 |
| |
54 |
| |
55 |
| |
56 |
| |
57 |
| |
58 |
| |
59 |
| |
60 |
| |
61 |
| |
62 |
| |
63 |
| |
64 |
| |
65 |
| |
66 |
| |
67 |
| |
68 |
| |
69 |
| |
70 |
| public class XMLWriter extends XMLFilterImpl implements LexicalHandler { |
71 |
| |
72 |
| private static final String PAD_TEXT = " "; |
73 |
| |
74 |
| protected static final String[] LEXICAL_HANDLER_NAMES = { |
75 |
| "http://xml.org/sax/properties/lexical-handler", |
76 |
| "http://xml.org/sax/handlers/LexicalHandler" |
77 |
| }; |
78 |
| |
79 |
| protected static final OutputFormat DEFAULT_FORMAT = new OutputFormat(); |
80 |
| |
81 |
| |
82 |
| private boolean resolveEntityRefs = true; |
83 |
| |
84 |
| |
85 |
| |
86 |
| protected int lastOutputNodeType; |
87 |
| |
88 |
| |
89 |
| protected boolean preserve=false; |
90 |
| |
91 |
| |
92 |
| protected Writer writer; |
93 |
| |
94 |
| |
95 |
| private NamespaceStack namespaceStack = new NamespaceStack(); |
96 |
| |
97 |
| |
98 |
| private OutputFormat format; |
99 |
| |
100 |
| |
101 |
| private boolean escapeText = true; |
102 |
| |
103 |
| |
104 |
| private int indentLevel = 0; |
105 |
| |
106 |
| |
107 |
| private StringBuffer buffer = new StringBuffer(); |
108 |
| |
109 |
| |
110 |
| private boolean charactersAdded = false; |
111 |
| private char lastChar; |
112 |
| |
113 |
| |
114 |
| private boolean autoFlush; |
115 |
| |
116 |
| |
117 |
| private LexicalHandler lexicalHandler; |
118 |
| |
119 |
| |
120 |
| private boolean showCommentsInDTDs; |
121 |
| |
122 |
| |
123 |
| private boolean inDTD; |
124 |
| |
125 |
| |
126 |
| private Map namespacesMap; |
127 |
| |
128 |
| |
129 |
| |
130 |
| |
131 |
| |
132 |
| |
133 |
| private int maximumAllowedCharacter; |
134 |
| |
135 |
| |
136 |
32
| public XMLWriter(Writer writer) {
|
137 |
32
| this( writer, DEFAULT_FORMAT );
|
138 |
| } |
139 |
| |
140 |
4206
| public XMLWriter(Writer writer, OutputFormat format) {
|
141 |
4206
| this.writer = writer;
|
142 |
4206
| this.format = format;
|
143 |
4206
| namespaceStack.push(Namespace.NO_NAMESPACE);
|
144 |
| } |
145 |
| |
146 |
4
| public XMLWriter() {
|
147 |
4
| this.format = DEFAULT_FORMAT;
|
148 |
4
| this.writer = new BufferedWriter( new OutputStreamWriter( System.out ) );
|
149 |
4
| this.autoFlush = true;
|
150 |
4
| namespaceStack.push(Namespace.NO_NAMESPACE);
|
151 |
| } |
152 |
| |
153 |
4
| public XMLWriter(OutputStream out) throws UnsupportedEncodingException {
|
154 |
4
| this.format = DEFAULT_FORMAT;
|
155 |
4
| this.writer = createWriter(out, format.getEncoding());
|
156 |
4
| this.autoFlush = true;
|
157 |
4
| namespaceStack.push(Namespace.NO_NAMESPACE);
|
158 |
| } |
159 |
| |
160 |
110
| public XMLWriter(OutputStream out, OutputFormat format) throws UnsupportedEncodingException {
|
161 |
110
| this.format = format;
|
162 |
110
| this.writer = createWriter(out, format.getEncoding());
|
163 |
110
| this.autoFlush = true;
|
164 |
110
| namespaceStack.push(Namespace.NO_NAMESPACE);
|
165 |
| } |
166 |
| |
167 |
14
| public XMLWriter(OutputFormat format) throws UnsupportedEncodingException {
|
168 |
14
| this.format = format;
|
169 |
14
| this.writer = createWriter( System.out, format.getEncoding() );
|
170 |
14
| this.autoFlush = true;
|
171 |
14
| namespaceStack.push(Namespace.NO_NAMESPACE);
|
172 |
| } |
173 |
| |
174 |
4
| public void setWriter(Writer writer) {
|
175 |
4
| this.writer = writer;
|
176 |
4
| this.autoFlush = false;
|
177 |
| } |
178 |
| |
179 |
14
| public void setOutputStream(OutputStream out) throws UnsupportedEncodingException {
|
180 |
14
| this.writer = createWriter(out, format.getEncoding());
|
181 |
14
| this.autoFlush = true;
|
182 |
| } |
183 |
| |
184 |
| |
185 |
| |
186 |
| |
187 |
| |
188 |
| |
189 |
| |
190 |
0
| public boolean isEscapeText() {
|
191 |
0
| return escapeText;
|
192 |
| } |
193 |
| |
194 |
| |
195 |
| |
196 |
| |
197 |
| |
198 |
| |
199 |
| |
200 |
2
| public void setEscapeText(boolean escapeText) {
|
201 |
2
| this.escapeText = escapeText;
|
202 |
| } |
203 |
| |
204 |
| |
205 |
| |
206 |
| |
207 |
| |
208 |
| |
209 |
| |
210 |
| |
211 |
| |
212 |
0
| public void setIndentLevel(int indentLevel) {
|
213 |
0
| this.indentLevel = indentLevel;
|
214 |
| } |
215 |
| |
216 |
| |
217 |
| |
218 |
| |
219 |
| |
220 |
| |
221 |
748134
| public int getMaximumAllowedCharacter() {
|
222 |
748134
| if (maximumAllowedCharacter == 0) {
|
223 |
4322
| maximumAllowedCharacter = defaultMaximumAllowedCharacter();
|
224 |
| } |
225 |
748134
| return maximumAllowedCharacter;
|
226 |
| } |
227 |
| |
228 |
| |
229 |
| |
230 |
| |
231 |
| |
232 |
| |
233 |
| |
234 |
| |
235 |
| |
236 |
| |
237 |
| |
238 |
2
| public void setMaximumAllowedCharacter(int maximumAllowedCharacter) {
|
239 |
2
| this.maximumAllowedCharacter = maximumAllowedCharacter;
|
240 |
| } |
241 |
| |
242 |
| |
243 |
132
| public void flush() throws IOException {
|
244 |
132
| writer.flush();
|
245 |
| } |
246 |
| |
247 |
| |
248 |
36
| public void close() throws IOException {
|
249 |
36
| writer.close();
|
250 |
| } |
251 |
| |
252 |
| |
253 |
190
| public void println() throws IOException {
|
254 |
190
| writer.write( format.getLineSeparator() );
|
255 |
| } |
256 |
| |
257 |
| |
258 |
| |
259 |
| |
260 |
| |
261 |
0
| public void write(Attribute attribute) throws IOException {
|
262 |
0
| writeAttribute(attribute);
|
263 |
| |
264 |
0
| if ( autoFlush ) {
|
265 |
0
| flush();
|
266 |
| } |
267 |
| } |
268 |
| |
269 |
| |
270 |
| |
271 |
| |
272 |
| |
273 |
| |
274 |
| |
275 |
| |
276 |
| |
277 |
| |
278 |
| |
279 |
| |
280 |
| |
281 |
| |
282 |
| |
283 |
190
| public void write(Document doc) throws IOException {
|
284 |
190
| writeDeclaration();
|
285 |
| |
286 |
190
| if (doc.getDocType() != null) {
|
287 |
2
| indent();
|
288 |
2
| writeDocType(doc.getDocType());
|
289 |
| } |
290 |
| |
291 |
190
| for ( int i = 0, size = doc.nodeCount(); i < size; i++ ) {
|
292 |
190
| Node node = doc.node(i);
|
293 |
190
| writeNode( node );
|
294 |
| } |
295 |
190
| writePrintln();
|
296 |
| |
297 |
190
| if ( autoFlush ) {
|
298 |
126
| flush();
|
299 |
| } |
300 |
| } |
301 |
| |
302 |
| |
303 |
| |
304 |
| |
305 |
| |
306 |
| |
307 |
| |
308 |
4138
| public void write(Element element) throws IOException {
|
309 |
4138
| writeElement(element);
|
310 |
| |
311 |
4138
| if ( autoFlush ) {
|
312 |
4
| flush();
|
313 |
| } |
314 |
| } |
315 |
| |
316 |
| |
317 |
| |
318 |
| |
319 |
| |
320 |
| |
321 |
0
| public void write(CDATA cdata) throws IOException {
|
322 |
0
| writeCDATA( cdata.getText() );
|
323 |
| |
324 |
0
| if ( autoFlush ) {
|
325 |
0
| flush();
|
326 |
| } |
327 |
| } |
328 |
| |
329 |
| |
330 |
| |
331 |
| |
332 |
| |
333 |
0
| public void write(Comment comment) throws IOException {
|
334 |
0
| writeComment( comment.getText() );
|
335 |
| |
336 |
0
| if ( autoFlush ) {
|
337 |
0
| flush();
|
338 |
| } |
339 |
| } |
340 |
| |
341 |
| |
342 |
| |
343 |
| |
344 |
| |
345 |
0
| public void write(DocumentType docType) throws IOException {
|
346 |
0
| writeDocType(docType);
|
347 |
| |
348 |
0
| if ( autoFlush ) {
|
349 |
0
| flush();
|
350 |
| } |
351 |
| } |
352 |
| |
353 |
| |
354 |
| |
355 |
| |
356 |
| |
357 |
| |
358 |
0
| public void write(Entity entity) throws IOException {
|
359 |
0
| writeEntity( entity );
|
360 |
| |
361 |
0
| if ( autoFlush ) {
|
362 |
0
| flush();
|
363 |
| } |
364 |
| } |
365 |
| |
366 |
| |
367 |
| |
368 |
| |
369 |
| |
370 |
| |
371 |
0
| public void write(Namespace namespace) throws IOException {
|
372 |
0
| writeNamespace(namespace);
|
373 |
| |
374 |
0
| if ( autoFlush ) {
|
375 |
0
| flush();
|
376 |
| } |
377 |
| } |
378 |
| |
379 |
| |
380 |
| |
381 |
| |
382 |
| |
383 |
0
| public void write(ProcessingInstruction processingInstruction) throws IOException {
|
384 |
0
| writeProcessingInstruction(processingInstruction);
|
385 |
| |
386 |
0
| if ( autoFlush ) {
|
387 |
0
| flush();
|
388 |
| } |
389 |
| } |
390 |
| |
391 |
| |
392 |
| |
393 |
| |
394 |
| |
395 |
| |
396 |
0
| public void write(String text) throws IOException {
|
397 |
0
| writeString(text);
|
398 |
| |
399 |
0
| if ( autoFlush ) {
|
400 |
0
| flush();
|
401 |
| } |
402 |
| } |
403 |
| |
404 |
| |
405 |
| |
406 |
| |
407 |
| |
408 |
0
| public void write(Text text) throws IOException {
|
409 |
0
| writeString(text.getText());
|
410 |
| |
411 |
0
| if ( autoFlush ) {
|
412 |
0
| flush();
|
413 |
| } |
414 |
| } |
415 |
| |
416 |
| |
417 |
| |
418 |
| |
419 |
| |
420 |
2
| public void write(Node node) throws IOException {
|
421 |
2
| writeNode(node);
|
422 |
| |
423 |
2
| if ( autoFlush ) {
|
424 |
0
| flush();
|
425 |
| } |
426 |
| } |
427 |
| |
428 |
| |
429 |
| |
430 |
| |
431 |
| |
432 |
| |
433 |
2
| public void write(Object object) throws IOException {
|
434 |
2
| if (object instanceof Node) {
|
435 |
2
| write((Node) object);
|
436 |
| } |
437 |
0
| else if (object instanceof String) {
|
438 |
0
| write((String) object);
|
439 |
| } |
440 |
0
| else if (object instanceof List) {
|
441 |
0
| List list = (List) object;
|
442 |
0
| for ( int i = 0, size = list.size(); i < size; i++ ) {
|
443 |
0
| write( list.get(i) );
|
444 |
| } |
445 |
| } |
446 |
0
| else if (object != null) {
|
447 |
0
| throw new IOException( "Invalid object: " + object );
|
448 |
| } |
449 |
| } |
450 |
| |
451 |
| |
452 |
| |
453 |
| |
454 |
| |
455 |
| |
456 |
| |
457 |
| |
458 |
0
| public void writeOpen(Element element) throws IOException {
|
459 |
0
| writer.write("<");
|
460 |
0
| writer.write( element.getQualifiedName() );
|
461 |
0
| writeAttributes(element);
|
462 |
0
| writer.write(">");
|
463 |
| } |
464 |
| |
465 |
| |
466 |
| |
467 |
| |
468 |
| |
469 |
0
| public void writeClose(Element element) throws IOException {
|
470 |
0
| writeClose( element.getQualifiedName() );
|
471 |
| } |
472 |
| |
473 |
| |
474 |
| |
475 |
| |
476 |
0
| public void parse(InputSource source) throws IOException, SAXException {
|
477 |
0
| installLexicalHandler();
|
478 |
0
| super.parse(source);
|
479 |
| } |
480 |
| |
481 |
| |
482 |
0
| public void setProperty(String name, Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
|
483 |
0
| for (int i = 0; i < LEXICAL_HANDLER_NAMES.length; i++) {
|
484 |
0
| if (LEXICAL_HANDLER_NAMES[i].equals(name)) {
|
485 |
0
| setLexicalHandler((LexicalHandler) value);
|
486 |
0
| return;
|
487 |
| } |
488 |
| } |
489 |
0
| super.setProperty(name, value);
|
490 |
| } |
491 |
| |
492 |
0
| public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
|
493 |
0
| for (int i = 0; i < LEXICAL_HANDLER_NAMES.length; i++) {
|
494 |
0
| if (LEXICAL_HANDLER_NAMES[i].equals(name)) {
|
495 |
0
| return getLexicalHandler();
|
496 |
| } |
497 |
| } |
498 |
0
| return super.getProperty(name);
|
499 |
| } |
500 |
| |
501 |
0
| public void setLexicalHandler (LexicalHandler handler) {
|
502 |
0
| if (handler == null) {
|
503 |
0
| throw new NullPointerException("Null lexical handler");
|
504 |
| } |
505 |
| else { |
506 |
0
| this.lexicalHandler = handler;
|
507 |
| } |
508 |
| } |
509 |
| |
510 |
0
| public LexicalHandler getLexicalHandler(){
|
511 |
0
| return lexicalHandler;
|
512 |
| } |
513 |
| |
514 |
| |
515 |
| |
516 |
| |
517 |
2
| public void setDocumentLocator(Locator locator) {
|
518 |
2
| super.setDocumentLocator(locator);
|
519 |
| } |
520 |
| |
521 |
6
| public void startDocument() throws SAXException {
|
522 |
6
| try {
|
523 |
6
| writeDeclaration();
|
524 |
6
| super.startDocument();
|
525 |
| } |
526 |
| catch (IOException e) { |
527 |
0
| handleException(e);
|
528 |
| } |
529 |
| } |
530 |
| |
531 |
6
| public void endDocument() throws SAXException {
|
532 |
6
| super.endDocument();
|
533 |
| |
534 |
6
| if ( autoFlush ) {
|
535 |
0
| try {
|
536 |
0
| flush();
|
537 |
| } catch ( IOException e) {} |
538 |
| } |
539 |
| } |
540 |
| |
541 |
0
| public void startPrefixMapping(String prefix, String uri) throws SAXException {
|
542 |
0
| if ( namespacesMap == null ) {
|
543 |
0
| namespacesMap = new HashMap();
|
544 |
| } |
545 |
0
| namespacesMap.put(prefix, uri);
|
546 |
0
| super.startPrefixMapping(prefix, uri);
|
547 |
| } |
548 |
| |
549 |
0
| public void endPrefixMapping(String prefix) throws SAXException {
|
550 |
0
| super.endPrefixMapping(prefix);
|
551 |
| } |
552 |
| |
553 |
12
| public void startElement(String namespaceURI, String localName, String qName, Attributes attributes) throws SAXException {
|
554 |
12
| try {
|
555 |
12
| charactersAdded = false;
|
556 |
| |
557 |
12
| writePrintln();
|
558 |
12
| indent();
|
559 |
12
| writer.write("<");
|
560 |
12
| writer.write(qName);
|
561 |
12
| writeNamespaces();
|
562 |
12
| writeAttributes( attributes );
|
563 |
12
| writer.write(">");
|
564 |
12
| ++indentLevel;
|
565 |
12
| lastOutputNodeType = Node.ELEMENT_NODE;
|
566 |
| |
567 |
12
| super.startElement( namespaceURI, localName, qName, attributes );
|
568 |
| } |
569 |
| catch (IOException e) { |
570 |
0
| handleException(e);
|
571 |
| } |
572 |
| } |
573 |
| |
574 |
12
| public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
|
575 |
12
| try {
|
576 |
12
| charactersAdded = false;
|
577 |
12
| --indentLevel;
|
578 |
12
| if ( lastOutputNodeType == Node.ELEMENT_NODE ) {
|
579 |
6
| writePrintln();
|
580 |
6
| indent();
|
581 |
| } |
582 |
| |
583 |
| |
584 |
| |
585 |
12
| boolean hadContent = true;
|
586 |
12
| if ( hadContent ) {
|
587 |
12
| writeClose(qName);
|
588 |
| } |
589 |
| else { |
590 |
0
| writeEmptyElementClose(qName);
|
591 |
| } |
592 |
12
| lastOutputNodeType = Node.ELEMENT_NODE;
|
593 |
| |
594 |
12
| super.endElement( namespaceURI, localName, qName );
|
595 |
| } |
596 |
| catch (IOException e) { |
597 |
0
| handleException(e);
|
598 |
| } |
599 |
| } |
600 |
| |
601 |
28
| public void characters(char[] ch, int start, int length) throws SAXException {
|
602 |
28
| if (ch == null || ch.length == 0 || length <= 0) {
|
603 |
2
| return;
|
604 |
| } |
605 |
| |
606 |
26
| try {
|
607 |
| |
608 |
| |
609 |
| |
610 |
| |
611 |
| |
612 |
| |
613 |
26
| String string = new String(ch, start, length);
|
614 |
| |
615 |
26
| if (escapeText) {
|
616 |
24
| string = escapeElementEntities(string);
|
617 |
| } |
618 |
| |
619 |
26
| if (format.isTrimText()) {
|
620 |
24
| if ((lastOutputNodeType == Node.TEXT_NODE) && !charactersAdded) {
|
621 |
0
| writer.write(" ");
|
622 |
24
| } else if (charactersAdded && Character.isWhitespace(lastChar)) {
|
623 |
2
| writer.write(lastChar);
|
624 |
| } |
625 |
| |
626 |
24
| String delim = "";
|
627 |
24
| StringTokenizer tokens = new StringTokenizer(string);
|
628 |
24
| while (tokens.hasMoreTokens()) {
|
629 |
30
| writer.write(delim);
|
630 |
30
| writer.write(tokens.nextToken());
|
631 |
30
| delim = " ";
|
632 |
| } |
633 |
| } else { |
634 |
2
| writer.write(string);
|
635 |
| } |
636 |
| |
637 |
26
| charactersAdded = true;
|
638 |
26
| lastChar = ch[start + length - 1];
|
639 |
26
| lastOutputNodeType = Node.TEXT_NODE;
|
640 |
| |
641 |
26
| super.characters(ch, start, length);
|
642 |
| } |
643 |
| catch (IOException e) { |
644 |
0
| handleException(e);
|
645 |
| } |
646 |
| } |
647 |
| |
648 |
0
| public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
|
649 |
0
| super.ignorableWhitespace(ch, start, length);
|
650 |
| } |
651 |
| |
652 |
0
| public void processingInstruction(String target, String data) throws SAXException {
|
653 |
0
| try {
|
654 |
0
| indent();
|
655 |
0
| writer.write("<?");
|
656 |
0
| writer.write(target);
|
657 |
0
| writer.write(" ");
|
658 |
0
| writer.write(data);
|
659 |
0
| writer.write("?>");
|
660 |
0
| writePrintln();
|
661 |
0
| lastOutputNodeType = Node.PROCESSING_INSTRUCTION_NODE;
|
662 |
| |
663 |
0
| super.processingInstruction(target, data);
|
664 |
| } |
665 |
| catch (IOException e) { |
666 |
0
| handleException(e);
|
667 |
| } |
668 |
| } |
669 |
| |
670 |
| |
671 |
| |
672 |
| |
673 |
| |
674 |
0
| public void notationDecl(String name, String publicID, String systemID) throws SAXException {
|
675 |
0
| super.notationDecl(name, publicID, systemID);
|
676 |
| } |
677 |
| |
678 |
0
| public void unparsedEntityDecl(String name, String publicID, String systemID, String notationName) throws SAXException {
|
679 |
0
| super.unparsedEntityDecl(name, publicID, systemID, notationName);
|
680 |
| } |
681 |
| |
682 |
| |
683 |
| |
684 |
| |
685 |
0
| public void startDTD(String name, String publicID, String systemID) throws SAXException {
|
686 |
0
| inDTD = true;
|
687 |
0
| try {
|
688 |
0
| writeDocType(name, publicID, systemID);
|
689 |
| } |
690 |
| catch (IOException e) { |
691 |
0
| handleException(e);
|
692 |
| } |
693 |
| |
694 |
0
| if (lexicalHandler != null) {
|
695 |
0
| lexicalHandler.startDTD(name, publicID, systemID);
|
696 |
| } |
697 |
| } |
698 |
| |
699 |
0
| public void endDTD() throws SAXException {
|
700 |
0
| inDTD = false;
|
701 |
0
| if (lexicalHandler != null) {
|
702 |
0
| lexicalHandler.endDTD();
|
703 |
| } |
704 |
| } |
705 |
| |
706 |
0
| public void startCDATA() throws SAXException {
|
707 |
0
| try {
|
708 |
0
| writer.write( "<![CDATA[" );
|
709 |
| } |
710 |
| catch (IOException e) { |
711 |
0
| handleException(e);
|
712 |
| } |
713 |
| |
714 |
0
| if (lexicalHandler != null) {
|
715 |
0
| lexicalHandler.startCDATA();
|
716 |
| } |
717 |
| } |
718 |
| |
719 |
0
| public void endCDATA() throws SAXException {
|
720 |
0
| try {
|
721 |
0
| writer.write( "]]>" );
|
722 |
| } |
723 |
| catch (IOException e) { |
724 |
0
| handleException(e);
|
725 |
| } |
726 |
| |
727 |
0
| if (lexicalHandler != null) {
|
728 |
0
| lexicalHandler.endCDATA();
|
729 |
| } |
730 |
| } |
731 |
| |
732 |
0
| public void startEntity(String name) throws SAXException {
|
733 |
0
| try {
|
734 |
0
| writeEntityRef(name);
|
735 |
| } |
736 |
| catch (IOException e) { |
737 |
0
| handleException(e);
|
738 |
| } |
739 |
| |
740 |
0
| if (lexicalHandler != null) {
|
741 |
0
| lexicalHandler.startEntity(name);
|
742 |
| } |
743 |
| } |
744 |
| |
745 |
0
| public void endEntity(String name) throws SAXException {
|
746 |
0
| if (lexicalHandler != null) {
|
747 |
0
| lexicalHandler.endEntity(name);
|
748 |
| } |
749 |
| } |
750 |
| |
751 |
0
| public void comment(char[] ch, int start, int length) throws SAXException {
|
752 |
0
| if ( showCommentsInDTDs || ! inDTD ) {
|
753 |
0
| try {
|
754 |
0
| charactersAdded = false;
|
755 |
0
| writeComment( new String(ch, start, length) );
|
756 |
| } |
757 |
| catch (IOException e) { |
758 |
0
| handleException(e);
|
759 |
| } |
760 |
| } |
761 |
| |
762 |
0
| if (lexicalHandler != null) {
|
763 |
0
| lexicalHandler.comment(ch, start, length);
|
764 |
| } |
765 |
| } |
766 |
| |
767 |
| |
768 |
| |
769 |
| |
770 |
| |
771 |
35438
| protected void writeElement(Element element) throws IOException {
|
772 |
35438
| int size = element.nodeCount();
|
773 |
35438
| String qualifiedName = element.getQualifiedName();
|
774 |
| |
775 |
35438
| writePrintln();
|
776 |
35438
| indent();
|
777 |
| |
778 |
35438
| writer.write("<");
|
779 |
35438
| writer.write(qualifiedName);
|
780 |
| |
781 |
35438
| int previouslyDeclaredNamespaces = namespaceStack.size();
|
782 |
35438
| Namespace ns = element.getNamespace();
|
783 |
35438
| if (isNamespaceDeclaration( ns ) ) {
|
784 |
1162
| namespaceStack.push(ns);
|
785 |
1162
| writeNamespace(ns);
|
786 |
| } |
787 |
| |
788 |
| |
789 |
35438
| boolean textOnly = true;
|
790 |
35438
| for ( int i = 0; i < size; i++ ) {
|
791 |
95188
| Node node = element.node(i);
|
792 |
95188
| if ( node instanceof Namespace ) {
|
793 |
180
| Namespace additional = (Namespace) node;
|
794 |
180
| if (isNamespaceDeclaration( additional ) ) {
|
795 |
32
| namespaceStack.push(additional);
|
796 |
32
| writeNamespace(additional);
|
797 |
| } |
798 |
| } |
799 |
95008
| else if ( node instanceof Element) {
|
800 |
31110
| textOnly = false;
|
801 |
| } |
802 |
63898
| else if ( node instanceof Comment) {
|
803 |
822
| textOnly = false;
|
804 |
| } |
805 |
| } |
806 |
| |
807 |
35438
| writeAttributes(element);
|
808 |
| |
809 |
35438
| lastOutputNodeType = Node.ELEMENT_NODE;
|
810 |
| |
811 |
35438
| if ( size <= 0 ) {
|
812 |
428
| writeEmptyElementClose(qualifiedName);
|
813 |
| } |
814 |
| else { |
815 |
35010
| writer.write(">");
|
816 |
35010
| if ( textOnly ) {
|
817 |
| |
818 |
| |
819 |
27174
| writeElementContent(element);
|
820 |
| } |
821 |
| else { |
822 |
| |
823 |
7836
| ++indentLevel;
|
824 |
| |
825 |
7836
| writeElementContent(element);
|
826 |
| |
827 |
7836
| --indentLevel;
|
828 |
| |
829 |
7836
| writePrintln();
|
830 |
7836
| indent();
|
831 |
| } |
832 |
35010
| writer.write("</");
|
833 |
35010
| writer.write(qualifiedName);
|
834 |
35010
| writer.write(">");
|
835 |
| } |
836 |
| |
837 |
| |
838 |
35438
| while (namespaceStack.size() > previouslyDeclaredNamespaces) {
|
839 |
1198
| namespaceStack.pop();
|
840 |
| } |
841 |
| |
842 |
35438
| lastOutputNodeType = Node.ELEMENT_NODE;
|
843 |
| } |
844 |
| |
845 |
| |
846 |
| |
847 |
| |
848 |
| |
849 |
| |
850 |
168
| protected final boolean isElementSpacePreserved(Element element) {
|
851 |
168
| final Attribute attr = (Attribute)element.attribute("space");
|
852 |
168
| boolean preserveFound=preserve;
|
853 |
168
| if (attr!=null) {
|
854 |
10
| if ("xml".equals(attr.getNamespacePrefix()) &&
|
855 |
| "preserve".equals(attr.getText())) { |
856 |
8
| preserveFound = true;
|
857 |
| } |
858 |
| else { |
859 |
2
| preserveFound = false;
|
860 |
| } |
861 |
| } |
862 |
168
| return preserveFound;
|
863 |
| } |
864 |
| |
865 |
| |
866 |
| |
867 |
| |
868 |
| |
869 |
| |
870 |
35010
| protected void writeElementContent(Element element) throws IOException {
|
871 |
35010
| boolean trim = format.isTrimText();
|
872 |
35010
| boolean oldPreserve=preserve;
|
873 |
35010
| if (trim) {
|
874 |
168
| preserve=isElementSpacePreserved(element);
|
875 |
168
| trim = !preserve;
|
876 |
| } |
877 |
35010
| if (trim) {
|
878 |
| |
879 |
| |
880 |
146
| Text lastTextNode = null;
|
881 |
146
| StringBuffer buffer = null;
|
882 |
146
| boolean textOnly = true;
|
883 |
146
| for ( int i = 0, size = element.nodeCount(); i < size; i++ ) {
|
884 |
256
| Node node = element.node(i);
|
885 |
256
| if ( node instanceof Text ) {
|
886 |
132
| if ( lastTextNode == null ) {
|
887 |
90
| lastTextNode = (Text) node;
|
888 |
| } |
889 |
| else { |
890 |
42
| if (buffer == null) {
|
891 |
16
| buffer = new StringBuffer( lastTextNode.getText() );
|
892 |
| } |
893 |
42
| buffer.append( ((Text) node).getText() );
|
894 |
| } |
895 |
| } |
896 |
| else { |
897 |
124
| if (!textOnly && format.isPadText()) {
|
898 |
0
| writer.write(PAD_TEXT);
|
899 |
| } |
900 |
| |
901 |
124
| textOnly = false;
|
902 |
| |
903 |
124
| if ( lastTextNode != null ) {
|
904 |
30
| if ( buffer != null ) {
|
905 |
4
| writeString( buffer.toString() );
|
906 |
4
| buffer = null;
|
907 |
| } |
908 |
| else { |
909 |
26
| writeString( lastTextNode.getText() );
|
910 |
| } |
911 |
30
| lastTextNode = null;
|
912 |
| |
913 |
30
| if (format.isPadText()) {
|
914 |
0
| writer.write(PAD_TEXT);
|
915 |
| } |
916 |
| } |
917 |
124
| writeNode(node);
|
918 |
| } |
919 |
| } |
920 |
146
| if ( lastTextNode != null ) {
|
921 |
60
| if (!textOnly && format.isPadText()) {
|
922 |
0
| writer.write(PAD_TEXT);
|
923 |
| } |
924 |
60
| if ( buffer != null ) {
|
925 |
12
| writeString( buffer.toString() );
|
926 |
12
| buffer = null;
|
927 |
| } |
928 |
| else { |
929 |
48
| writeString( lastTextNode.getText() );
|
930 |
| } |
931 |
60
| lastTextNode = null;
|
932 |
| } |
933 |
| } |
934 |
| else { |
935 |
34864
| Node lastTextNode = null;
|
936 |
34864
| for ( int i = 0, size = element.nodeCount(); i < size; i++ ) {
|
937 |
94932
| Node node = element.node(i);
|
938 |
94932
| if (node instanceof Text) {
|
939 |
62938
| writeNode(node);
|
940 |
62938
| lastTextNode = node;
|
941 |
| } else { |
942 |
31994
| if ((lastTextNode != null) && format.isPadText()) {
|
943 |
2
| writer.write(PAD_TEXT);
|
944 |
| } |
945 |
31994
| writeNode(node);
|
946 |
31994
| if ((lastTextNode != null) && format.isPadText()) {
|
947 |
2
| writer.write(PAD_TEXT);
|
948 |
| } |
949 |
31994
| lastTextNode = null;
|
950 |
| } |
951 |
| } |
952 |
| } |
953 |
35010
| preserve=oldPreserve;
|
954 |
| } |
955 |
4
| protected void writeCDATA(String text) throws IOException {
|
956 |
4
| writer.write( "<![CDATA[" );
|
957 |
4
| writer.write( text );
|
958 |
4
| writer.write( "]]>" );
|
959 |
| |
960 |
4
| lastOutputNodeType = Node.CDATA_SECTION_NODE;
|
961 |
| } |
962 |
| |
963 |
2
| protected void writeDocType(DocumentType docType) throws IOException {
|
964 |
2
| if (docType != null) {
|
965 |
2
| docType.write( writer );
|
966 |
| |
967 |
2
| writePrintln();
|
968 |
| } |
969 |
| } |
970 |
| |
971 |
| |
972 |
1194
| protected void writeNamespace(Namespace namespace) throws IOException {
|
973 |
1194
| if ( namespace != null ) {
|
974 |
1194
| writeNamespace(namespace.getPrefix(), namespace.getURI());
|
975 |
| } |
976 |
| } |
977 |
| |
978 |
| |
979 |
| |
980 |
| |
981 |
12
| protected void writeNamespaces() throws IOException {
|
982 |
12
| if ( namespacesMap != null ) {
|
983 |
0
| for ( Iterator iter = namespacesMap.entrySet().iterator(); iter.hasNext(); ) {
|
984 |
0
| Map.Entry entry = (Map.Entry) iter.next();
|
985 |
0
| String prefix = (String) entry.getKey();
|
986 |
0
| String uri = (String) entry.getValue();
|
987 |
0
| writeNamespace(prefix, uri);
|
988 |
| } |
989 |
0
| namespacesMap = null;
|
990 |
| } |
991 |
| } |
992 |
| |
993 |
| |
994 |
| |
995 |
| |
996 |
1198
| protected void writeNamespace(String prefix, String uri) throws IOException {
|
997 |
1198
| if ( prefix != null && prefix.length() > 0 ) {
|
998 |
1106
| writer.write(" xmlns:");
|
999 |
1106
| writer.write(prefix);
|
1000 |
1106
| writer.write("=\"");
|
1001 |
| } |
1002 |
| else { |
1003 |
92
| writer.write(" xmlns=\"");
|
1004 |
| } |
1005 |
1198
| writer.write(uri);
|
1006 |
1198
| writer.write("\"");
|
1007 |
| } |
1008 |
| |
1009 |
0
| protected void writeProcessingInstruction(ProcessingInstruction processingInstruction) throws IOException {
|
1010 |
| |
1011 |
0
| writer.write( "<?" );
|
1012 |
0
| writer.write( processingInstruction.getName() );
|
1013 |
0
| writer.write( " " );
|
1014 |
0
| writer.write( processingInstruction.getText() );
|
1015 |
0
| writer.write( "?>" );
|
1016 |
0
| writePrintln();
|
1017 |
| |
1018 |
0
| lastOutputNodeType = Node.PROCESSING_INSTRUCTION_NODE;
|
1019 |
| } |
1020 |
| |
1021 |
90
| protected void writeString(String text) throws IOException {
|
1022 |
90
| if ( text != null && text.length() > 0 ) {
|
1023 |
86
| if ( escapeText ) {
|
1024 |
86
| text = escapeElementEntities(text);
|
1025 |
| } |
1026 |
| |
1027 |
| |
1028 |
| |
1029 |
| |
1030 |
| |
1031 |
| |
1032 |
| |
1033 |
86
| if (format.isTrimText()) {
|
1034 |
86
| boolean first = true;
|
1035 |
86
| StringTokenizer tokenizer = new StringTokenizer(text);
|
1036 |
86
| while (tokenizer.hasMoreTokens()) {
|
1037 |
252
| String token = tokenizer.nextToken();
|
1038 |
252
| if ( first ) {
|
1039 |
78
| first = false;
|
1040 |
78
| if ( lastOutputNodeType == Node.TEXT_NODE ) {
|
1041 |
0
| writer.write(" ");
|
1042 |
| } |
1043 |
| } |
1044 |
| else { |
1045 |
174
| writer.write(" ");
|
1046 |
| } |
1047 |
252
| writer.write(token);
|
1048 |
252
| lastOutputNodeType = Node.TEXT_NODE;
|
1049 |
| } |
1050 |
| } |
1051 |
| else { |
1052 |
0
| lastOutputNodeType = Node.TEXT_NODE;
|
1053 |
0
| writer.write(text);
|
1054 |
| } |
1055 |
| } |
1056 |
| } |
1057 |
| |
1058 |
| |
1059 |
| |
1060 |
| |
1061 |
| |
1062 |
| |
1063 |
62938
| protected void writeNodeText(Node node) throws IOException {
|
1064 |
62938
| String text = node.getText();
|
1065 |
62938
| if (text != null && text.length() > 0) {
|
1066 |
62938
| if (escapeText) {
|
1067 |
62938
| text = escapeElementEntities(text);
|
1068 |
| } |
1069 |
| |
1070 |
62938
| lastOutputNodeType = Node.TEXT_NODE;
|
1071 |
62938
| writer.write(text);
|
1072 |
| } |
1073 |
| } |
1074 |
| |
1075 |
95248
| protected void writeNode(Node node) throws IOException {
|
1076 |
95248
| int nodeType = node.getNodeType();
|
1077 |
95248
| switch (nodeType) {
|
1078 |
31300
| case Node.ELEMENT_NODE:
|
1079 |
31300
| writeElement((Element) node);
|
1080 |
31300
| break;
|
1081 |
0
| case Node.ATTRIBUTE_NODE:
|
1082 |
0
| writeAttribute((Attribute) node);
|
1083 |
0
| break;
|
1084 |
62938
| case Node.TEXT_NODE:
|
1085 |
62938
| writeNodeText(node);
|
1086 |
| |
1087 |
62938
| break;
|
1088 |
6
| case Node.CDATA_SECTION_NODE:
|
1089 |
6
| writeCDATA(node.getText());
|
1090 |
6
| break;
|
1091 |
0
| case Node.ENTITY_REFERENCE_NODE:
|
1092 |
0
| writeEntity((Entity) node);
|
1093 |
0
| break;
|
1094 |
0
| case Node.PROCESSING_INSTRUCTION_NODE:
|
1095 |
0
| writeProcessingInstruction((ProcessingInstruction) node);
|
1096 |
0
| break;
|
1097 |
822
| case Node.COMMENT_NODE:
|
1098 |
822
| writeComment(node.getText());
|
1099 |
822
| break;
|
1100 |
2
| case Node.DOCUMENT_NODE:
|
1101 |
2
| write((Document) node);
|
1102 |
2
| break;
|
1103 |
0
| case Node.DOCUMENT_TYPE_NODE:
|
1104 |
0
| writeDocType((DocumentType) node);
|
1105 |
0
| break;
|
1106 |
180
| case Node.NAMESPACE_NODE:
|
1107 |
| |
1108 |
| |
1109 |
180
| break;
|
1110 |
0
| default:
|
1111 |
0
| throw new IOException( "Invalid node type: " + node );
|
1112 |
| } |
1113 |
| } |
1114 |
| |
1115 |
| |
1116 |
| |
1117 |
| |
1118 |
0
| protected void installLexicalHandler() {
|
1119 |
0
| XMLReader parent = getParent();
|
1120 |
0
| if (parent == null) {
|
1121 |
0
| throw new NullPointerException("No parent for filter");
|
1122 |
| } |
1123 |
| |
1124 |
0
| for (int i = 0; i < LEXICAL_HANDLER_NAMES.length; i++) {
|
1125 |
0
| try {
|
1126 |
0
| parent.setProperty(LEXICAL_HANDLER_NAMES[i], this);
|
1127 |
0
| break;
|
1128 |
| } |
1129 |
| catch (SAXNotRecognizedException ex) { |
1130 |
| |
1131 |
| } |
1132 |
| catch (SAXNotSupportedException ex) { |
1133 |
| |
1134 |
| } |
1135 |
| } |
1136 |
| } |
1137 |
| |
1138 |
0
| protected void writeDocType(String name, String publicID, String systemID) throws IOException {
|
1139 |
0
| boolean hasPublic = false;
|
1140 |
| |
1141 |
0
| writer.write("<!DOCTYPE ");
|
1142 |
0
| writer.write(name);
|
1143 |
0
| if ((publicID != null) && (!publicID.equals(""))) {
|
1144 |
0
| writer.write(" PUBLIC \"");
|
1145 |
0
| writer.write(publicID);
|
1146 |
0
| writer.write("\"");
|
1147 |
0
| hasPublic = true;
|
1148 |
| } |
1149 |
0
| if ((systemID != null) && (!systemID.equals(""))) {
|
1150 |
0
| if (!hasPublic) {
|
1151 |
0
| writer.write(" SYSTEM");
|
1152 |
| } |
1153 |
0
| writer.write(" \"");
|
1154 |
0
| writer.write(systemID);
|
1155 |
0
| writer.write("\"");
|
1156 |
| } |
1157 |
0
| writer.write(">");
|
1158 |
0
| writePrintln();
|
1159 |
| } |
1160 |
| |
1161 |
0
| protected void writeEntity(Entity entity) throws IOException {
|
1162 |
0
| if (!resolveEntityRefs()) {
|
1163 |
0
| writeEntityRef( entity.getName() );
|
1164 |
| } else { |
1165 |
0
| writer.write(entity.getText());
|
1166 |
| } |
1167 |
| } |
1168 |
| |
1169 |
0
| protected void writeEntityRef(String name) throws IOException {
|
1170 |
0
| writer.write( "&" );
|
1171 |
0
| writer.write( name );
|
1172 |
0
| writer.write( ";" );
|
1173 |
| |
1174 |
0
| lastOutputNodeType = Node.ENTITY_REFERENCE_NODE;
|
1175 |
| } |
1176 |
| |
1177 |
822
| protected void writeComment(String text) throws IOException {
|
1178 |
822
| if (format.isNewlines()) {
|
1179 |
6
| println();
|
1180 |
6
| indent();
|
1181 |
| } |
1182 |
822
| writer.write( "<!--" );
|
1183 |
822
| writer.write( text );
|
1184 |
822
| writer.write( "-->" );
|
1185 |
| |
1186 |
822
| lastOutputNodeType = Node.COMMENT_NODE;
|
1187 |
| } |
1188 |
| |
1189 |
| |
1190 |
| |
1191 |
| |
1192 |
35438
| protected void writeAttributes( Element element ) throws IOException {
|
1193 |
| |
1194 |
| |
1195 |
| |
1196 |
| |
1197 |
| |
1198 |
35438
| for ( int i = 0, size = element.attributeCount(); i < size; i++ ) {
|
1199 |
6230
| Attribute attribute = element.attribute(i);
|
1200 |
6230
| Namespace ns = attribute.getNamespace();
|
1201 |
6230
| if (ns != null && ns != Namespace.NO_NAMESPACE && ns != Namespace.XML_NAMESPACE) {
|
1202 |
24
| String prefix = ns.getPrefix();
|
1203 |
24
| String uri = namespaceStack.getURI(prefix);
|
1204 |
24
| if (!ns.getURI().equals(uri)) {
|
1205 |
0
| writeNamespace(ns);
|
1206 |
0
| namespaceStack.push(ns);
|
1207 |
| } |
1208 |
| } |
1209 |
| |
1210 |
| |
1211 |
| |
1212 |
| |
1213 |
6230
| String attName = attribute.getName();
|
1214 |
6230
| if (attName.startsWith("xmlns:")) {
|
1215 |
6
| String prefix = attName.substring(6);
|
1216 |
6
| if (namespaceStack.getNamespaceForPrefix(prefix) == null) {
|
1217 |
4
| String uri = attribute.getValue();
|
1218 |
4
| namespaceStack.push(prefix, uri);
|
1219 |
4
| writeNamespace(prefix, uri);
|
1220 |
| } |
1221 |
6224
| } else if (attName.equals("xmlns")) {
|
1222 |
2
| if (namespaceStack.getDefaultNamespace() == null) {
|
1223 |
0
| String uri = attribute.getValue();
|
1224 |
0
| namespaceStack.push(null, uri);
|
1225 |
0
| writeNamespace(null, uri);
|
1226 |
| } |
1227 |
| } else { |
1228 |
6222
| char quote = format.getAttributeQuoteCharacter();
|
1229 |
6222
| writer.write(" ");
|
1230 |
6222
| writer.write(attribute.getQualifiedName());
|
1231 |
6222
| writer.write("=");
|
1232 |
6222
| writer.write(quote);
|
1233 |
6222
| writeEscapeAttributeEntities(attribute.getValue());
|
1234 |
6222
| writer.write(quote);
|
1235 |
| } |
1236 |
| } |
1237 |
| } |
1238 |
| |
1239 |
0
| protected void writeAttribute(Attribute attribute) throws IOException {
|
1240 |
0
| writer.write(" ");
|
1241 |
0
| writer.write(attribute.getQualifiedName());
|
1242 |
0
| writer.write("=");
|
1243 |
| |
1244 |
0
| char quote = format.getAttributeQuoteCharacter();
|
1245 |
0
| writer.write(quote);
|
1246 |
| |
1247 |
0
| writeEscapeAttributeEntities(attribute.getValue());
|
1248 |
| |
1249 |
0
| writer.write(quote);
|
1250 |
0
| lastOutputNodeType = Node.ATTRIBUTE_NODE;
|
1251 |
| } |
1252 |
| |
1253 |
12
| protected void writeAttributes(Attributes attributes) throws IOException {
|
1254 |
12
| for (int i = 0, size = attributes.getLength(); i < size; i++) {
|
1255 |
10
| writeAttribute( attributes, i );
|
1256 |
| } |
1257 |
| } |
1258 |
| |
1259 |
10
| protected void writeAttribute(Attributes attributes, int index) throws IOException {
|
1260 |
10
| char quote = format.getAttributeQuoteCharacter();
|
1261 |
10
| writer.write(" ");
|
1262 |
10
| writer.write(attributes.getQName(index));
|
1263 |
10
| writer.write("=");
|
1264 |
10
| writer.write(quote);
|
1265 |
10
| writeEscapeAttributeEntities(attributes.getValue(index));
|
1266 |
10
| writer.write(quote);
|
1267 |
| } |
1268 |
| |
1269 |
| |
1270 |
| |
1271 |
43300
| protected void indent() throws IOException {
|
1272 |
43300
| String indent = format.getIndent();
|
1273 |
43300
| if ( indent != null && indent.length() > 0 ) {
|
1274 |
272
| for ( int i = 0; i < indentLevel; i++ ) {
|
1275 |
320
| writer.write(indent);
|
1276 |
| } |
1277 |
| } |
1278 |
| } |
1279 |
| |
1280 |
| |
1281 |
| |
1282 |
| |
1283 |
| |
1284 |
| |
1285 |
43484
| protected void writePrintln() throws IOException {
|
1286 |
43484
| if (format.isNewlines()) {
|
1287 |
308
| writer.write( format.getLineSeparator() );
|
1288 |
| } |
1289 |
| } |
1290 |
| |
1291 |
| |
1292 |
| |
1293 |
| |
1294 |
142
| protected Writer createWriter(OutputStream outStream, String encoding) throws UnsupportedEncodingException {
|
1295 |
142
| return new BufferedWriter(
|
1296 |
| new OutputStreamWriter( outStream, encoding ) |
1297 |
| ); |
1298 |
| } |
1299 |
| |
1300 |
| |
1301 |
| |
1302 |
| |
1303 |
| |
1304 |
| |
1305 |
| |
1306 |
190
| protected void writeDeclaration() throws IOException {
|
1307 |
190
| String encoding = format.getEncoding();
|
1308 |
| |
1309 |
| |
1310 |
190
| if (! format.isSuppressDeclaration()) {
|
1311 |
| |
1312 |
184
| if (encoding.equals("UTF8")) {
|
1313 |
0
| writer.write("<?xml version=\"1.0\"");
|
1314 |
0
| if (!format.isOmitEncoding()) {
|
1315 |
0
| writer.write(" encoding=\"UTF-8\"");
|
1316 |
| } |
1317 |
0
| writer.write("?>");
|
1318 |
| } else { |
1319 |
184
| writer.write("<?xml version=\"1.0\"");
|
1320 |
184
| if (! format.isOmitEncoding()) {
|
1321 |
184
| writer.write(" encoding=\"" + encoding + "\"");
|
1322 |
| } |
1323 |
184
| writer.write("?>");
|
1324 |
| } |
1325 |
184
| if (format.isNewLineAfterDeclaration()) {
|
1326 |
184
| println();
|
1327 |
| } |
1328 |
| } |
1329 |
| } |
1330 |
| |
1331 |
12
| protected void writeClose(String qualifiedName) throws IOException {
|
1332 |
12
| writer.write("</");
|
1333 |
12
| writer.write(qualifiedName);
|
1334 |
12
| writer.write(">");
|
1335 |
| } |
1336 |
| |
1337 |
426
| protected void writeEmptyElementClose(String qualifiedName) throws IOException {
|
1338 |
| |
1339 |
426
| if (! format.isExpandEmptyElements()) {
|
1340 |
420
| writer.write("/>");
|
1341 |
| } else { |
1342 |
6
| writer.write("></");
|
1343 |
6
| writer.write(qualifiedName);
|
1344 |
6
| writer.write(">");
|
1345 |
| } |
1346 |
| } |
1347 |
| |
1348 |
0
| protected boolean isExpandEmptyElements() {
|
1349 |
0
| return format.isExpandEmptyElements();
|
1350 |
| } |
1351 |
| |
1352 |
| |
1353 |
| |
1354 |
| |
1355 |
| |
1356 |
| |
1357 |
63048
| protected String escapeElementEntities(String text) {
|
1358 |
63048
| char[] block = null;
|
1359 |
63048
| int i, last = 0, size = text.length();
|
1360 |
63048
| for ( i = 0; i < size; i++ ) {
|
1361 |
728272
| String entity = null;
|
1362 |
728272
| char c = text.charAt(i);
|
1363 |
728272
| switch( c ) {
|
1364 |
24
| case '<' :
|
1365 |
24
| entity = "<";
|
1366 |
24
| break;
|
1367 |
22
| case '>' :
|
1368 |
22
| entity = ">";
|
1369 |
22
| break;
|
1370 |
36
| case '&' :
|
1371 |
36
| entity = "&";
|
1372 |
36
| break;
|
1373 |
0
| case '\t': case '\n': case '\r':
|
1374 |
| |
1375 |
53806
| if (preserve) {
|
1376 |
4
| entity=String.valueOf(c);
|
1377 |
| } |
1378 |
53806
| break;
|
1379 |
674384
| default:
|
1380 |
674384
| if (c < 32 || shouldEncodeChar(c)) {
|
1381 |
2
| entity = "&#" + (int) c + ";";
|
1382 |
| } |
1383 |
674384
| break;
|
1384 |
| } |
1385 |
728272
| if (entity != null) {
|
1386 |
88
| if ( block == null ) {
|
1387 |
68
| block = text.toCharArray();
|
1388 |
| } |
1389 |
88
| buffer.append(block, last, i - last);
|
1390 |
88
| buffer.append(entity);
|
1391 |
88
| last = i + 1;
|
1392 |
| } |
1393 |
| } |
1394 |
63048
| if ( last == 0 ) {
|
1395 |
62980
| return text;
|
1396 |
| } |
1397 |
68
| if ( last < size ) {
|
1398 |
20
| if ( block == null ) {
|
1399 |
0
| block = text.toCharArray();
|
1400 |
| } |
1401 |
20
| buffer.append(block, last, i - last);
|
1402 |
| } |
1403 |
68
| String answer = buffer.toString();
|
1404 |
68
| buffer.setLength(0);
|
1405 |
68
| return answer;
|
1406 |
| } |
1407 |
| |
1408 |
| |
1409 |
6232
| protected void writeEscapeAttributeEntities(String text) throws IOException {
|
1410 |
6232
| if ( text != null ) {
|
1411 |
6232
| String escapedText = escapeAttributeEntities( text );
|
1412 |
6232
| writer.write( escapedText );
|
1413 |
| } |
1414 |
| } |
1415 |
| |
1416 |
| |
1417 |
| |
1418 |
| |
1419 |
6232
| protected String escapeAttributeEntities(String text) {
|
1420 |
6232
| char quote = format.getAttributeQuoteCharacter();
|
1421 |
| |
1422 |
6232
| char[] block = null;
|
1423 |
6232
| int i, last = 0, size = text.length();
|
1424 |
6232
| for ( i = 0; i < size; i++ ) {
|
1425 |
73752
| String entity = null;
|
1426 |
73752
| char c = text.charAt(i);
|
1427 |
73752
| switch( c ) {
|
1428 |
0
| case '<' :
|
1429 |
0
| entity = "<";
|
1430 |
0
| break;
|
1431 |
0
| case '>' :
|
1432 |
0
| entity = ">";
|
1433 |
0
| break;
|
1434 |
2
| case '\'' :
|
1435 |
2
| if (quote == '\'') {
|
1436 |
0
| entity = "'";
|
1437 |
| } |
1438 |
2
| break;
|
1439 |
0
| case '\"' :
|
1440 |
0
| if (quote == '\"') {
|
1441 |
0
| entity = """;
|
1442 |
| } |
1443 |
0
| break;
|
1444 |
0
| case '&' :
|
1445 |
0
| entity = "&";
|
1446 |
0
| break;
|
1447 |
0
| case '\t': case '\n': case '\r':
|
1448 |
| |
1449 |
0
| break;
|
1450 |
73750
| default:
|
1451 |
73750
| if (c < 32 || shouldEncodeChar(c)) {
|
1452 |
0
| entity = "&#" + (int) c + ";";
|
1453 |
| } |
1454 |
73750
| break;
|
1455 |
| } |
1456 |
73752
| if (entity != null) {
|
1457 |
0
| if ( block == null ) {
|
1458 |
0
| block = text.toCharArray();
|
1459 |
| } |
1460 |
0
| buffer.append(block, last, i - last);
|
1461 |
0
| buffer.append(entity);
|
1462 |
0
| last = i + 1;
|
1463 |
| } |
1464 |
| } |
1465 |
6232
| if ( last == 0 ) {
|
1466 |
6232
| return text;
|
1467 |
| } |
1468 |
0
| if ( last < size ) {
|
1469 |
0
| if ( block == null ) {
|
1470 |
0
| block = text.toCharArray();
|
1471 |
| } |
1472 |
0
| buffer.append(block, last, i - last);
|
1473 |
| } |
1474 |
0
| String answer = buffer.toString();
|
1475 |
0
| buffer.setLength(0);
|
1476 |
0
| return answer;
|
1477 |
| } |
1478 |
| |
1479 |
| |
1480 |
| |
1481 |
| |
1482 |
| |
1483 |
| |
1484 |
| |
1485 |
748134
| protected boolean shouldEncodeChar(char c) {
|
1486 |
748134
| int max = getMaximumAllowedCharacter();
|
1487 |
748134
| return max > 0 && c > max;
|
1488 |
| } |
1489 |
| |
1490 |
| |
1491 |
| |
1492 |
| |
1493 |
| |
1494 |
| |
1495 |
4322
| protected int defaultMaximumAllowedCharacter() {
|
1496 |
4322
| String encoding = format.getEncoding();
|
1497 |
4322
| if (encoding != null) {
|
1498 |
4322
| if (encoding.equals("US-ASCII")) {
|
1499 |
0
| return 127;
|
1500 |
| } |
1501 |
| } |
1502 |
| |
1503 |
4322
| return -1;
|
1504 |
| } |
1505 |
| |
1506 |
35618
| protected boolean isNamespaceDeclaration( Namespace ns ) {
|
1507 |
35618
| if (ns != null && ns != Namespace.XML_NAMESPACE) {
|
1508 |
35618
| String uri = ns.getURI();
|
1509 |
35618
| if ( uri != null ) {
|
1510 |
35618
| if ( ! namespaceStack.contains( ns ) ) {
|
1511 |
1194
| return true;
|
1512 |
| |
1513 |
| } |
1514 |
| } |
1515 |
| } |
1516 |
34424
| return false;
|
1517 |
| |
1518 |
| } |
1519 |
| |
1520 |
0
| protected void handleException(IOException e) throws SAXException {
|
1521 |
0
| throw new SAXException(e);
|
1522 |
| } |
1523 |
| |
1524 |
| |
1525 |
| |
1526 |
| |
1527 |
| |
1528 |
| |
1529 |
| |
1530 |
14
| protected OutputFormat getOutputFormat() {
|
1531 |
14
| return format;
|
1532 |
| } |
1533 |
| |
1534 |
0
| public boolean resolveEntityRefs() {
|
1535 |
0
| return resolveEntityRefs;
|
1536 |
| } |
1537 |
| |
1538 |
0
| public void setResolveEntityRefs(boolean resolve) {
|
1539 |
0
| this.resolveEntityRefs = resolve;
|
1540 |
| } |
1541 |
| } |
1542 |
| |
1543 |
| |
1544 |
| |
1545 |
| |
1546 |
| |
1547 |
| |
1548 |
| |
1549 |
| |
1550 |
| |
1551 |
| |
1552 |
| |
1553 |
| |
1554 |
| |
1555 |
| |
1556 |
| |
1557 |
| |
1558 |
| |
1559 |
| |
1560 |
| |
1561 |
| |
1562 |
| |
1563 |
| |
1564 |
| |
1565 |
| |
1566 |
| |
1567 |
| |
1568 |
| |
1569 |
| |
1570 |
| |
1571 |
| |
1572 |
| |
1573 |
| |
1574 |
| |
1575 |
| |
1576 |
| |
1577 |
| |
1578 |
| |
1579 |
| |
1580 |
| |
1581 |
| |
1582 |
| |
1583 |
| |
1584 |
| |
1585 |
| |
1586 |
| |
1587 |
| |
1588 |
| |
1589 |
| |