Source Code Cross Referenced for XMLEmitter.java in  » XML » saxonb » net » sf » saxon » event » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » saxonb » net.sf.saxon.event 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package net.sf.saxon.event;
002:
003:        import net.sf.saxon.charcode.UnicodeCharacterSet;
004:        import net.sf.saxon.om.XMLChar;
005:        import net.sf.saxon.om.FastStringBuffer;
006:        import net.sf.saxon.trans.DynamicError;
007:        import net.sf.saxon.trans.XPathException;
008:        import net.sf.saxon.tinytree.CharSlice;
009:        import net.sf.saxon.value.Whitespace;
010:
011:        import javax.xml.transform.OutputKeys;
012:        import javax.xml.transform.TransformerException;
013:        import javax.xml.transform.TransformerFactory;
014:        import javax.xml.transform.Templates;
015:        import javax.xml.transform.stream.StreamResult;
016:        import javax.xml.transform.stream.StreamSource;
017:        import java.util.Stack;
018:        import java.io.CharArrayWriter;
019:        import java.io.File;
020:
021:        /**
022:         * XMLEmitter is an Emitter that generates XML output
023:         * to a specified destination.
024:         */
025:
026:        public class XMLEmitter extends Emitter {
027:            protected boolean empty = true;
028:            protected boolean openStartTag = false;
029:            protected boolean declarationIsWritten = false;
030:            protected int elementCode;
031:
032:            protected boolean preferHex = false;
033:            protected boolean undeclareNamespaces = false;
034:            private boolean warningIssued = false;
035:
036:            // The element stack holds the display names (lexical QNames) of elements that
037:            // have been started but not finished. It is used to obtain the element name
038:            // for the end tag.
039:
040:            protected Stack elementStack = new Stack();
041:
042:            // Namecodes in the range 0..2048 are common. So for these codes,
043:            // we maintain a direct lookup from the namecode to the display name
044:            // that bypasses reference to the namepool
045:
046:            private String[] nameLookup = new String[2048];
047:
048:            private boolean indenting = false;
049:            private int indentSpaces = 3;
050:            private String indentChars = "\n                                                          ";
051:            private int totalAttributeLength = 0;
052:            private boolean requireWellFormed = false;
053:
054:            static boolean[] specialInText; // lookup table for special characters in text
055:            static boolean[] specialInAtt; // lookup table for special characters in attributes
056:            // create look-up table for ASCII characters that need special treatment
057:
058:            static {
059:                specialInText = new boolean[128];
060:                for (int i = 0; i <= 31; i++)
061:                    specialInText[i] = true; // allowed in XML 1.1 as character references
062:                for (int i = 32; i <= 127; i++)
063:                    specialInText[i] = false;
064:                specialInText[(char) 0] = true;
065:                // used to switch escaping on and off for mapped characters
066:                specialInText['\n'] = false;
067:                specialInText['\t'] = false;
068:                specialInText['\r'] = true;
069:                specialInText['<'] = true;
070:                specialInText['>'] = true;
071:                specialInText['&'] = true;
072:
073:                specialInAtt = new boolean[128];
074:                for (int i = 0; i <= 15; i++)
075:                    specialInAtt[i] = true; // allowed in XML 1.1 as character references
076:                for (int i = 16; i <= 127; i++)
077:                    specialInAtt[i] = false;
078:                specialInAtt[(char) 0] = true;
079:                // used to switch escaping on and off for mapped characters
080:                specialInAtt['\r'] = true;
081:                specialInAtt['\n'] = true;
082:                specialInAtt['\t'] = true;
083:                specialInAtt['<'] = true;
084:                specialInAtt['>'] = true;
085:                specialInAtt['&'] = true;
086:                specialInAtt['\"'] = true;
087:            }
088:
089:            /**
090:             * Start of the event stream. Nothing is done at this stage: the opening of the output
091:             * file is deferred until some content is written to it.
092:             */
093:
094:            public void open() throws XPathException {
095:            }
096:
097:            /**
098:             * Start of a document node. Nothing is done at this stage: the opening of the output
099:             * file is deferred until some content is written to it.
100:             */
101:
102:            public void startDocument(int properties) throws XPathException {
103:            }
104:
105:            /**
106:             * Notify the end of a document node
107:             */
108:
109:            public void endDocument() throws XPathException {
110:                if (!elementStack.isEmpty()) {
111:                    throw new IllegalStateException(
112:                            "Attempt to end document in serializer when elements are unclosed");
113:                }
114:            }
115:
116:            /**
117:             * Do the real work of starting the document. This happens when the first
118:             * content is written.
119:             * @throws XPathException
120:             */
121:
122:            protected void openDocument() throws XPathException {
123:                if (writer == null) {
124:                    makeWriter();
125:                }
126:                if (characterSet == null) {
127:                    characterSet = UnicodeCharacterSet.getInstance();
128:                }
129:                String rep = outputProperties
130:                        .getProperty(SaxonOutputKeys.CHARACTER_REPRESENTATION);
131:                if (rep != null) {
132:                    preferHex = (rep.trim().equalsIgnoreCase("hex"));
133:                }
134:                rep = outputProperties
135:                        .getProperty(SaxonOutputKeys.UNDECLARE_PREFIXES);
136:                if (rep != null) {
137:                    undeclareNamespaces = (rep.trim().equalsIgnoreCase("yes"));
138:                }
139:                writeDeclaration();
140:            }
141:
142:            /**
143:             * Output the XML declaration
144:             */
145:
146:            public void writeDeclaration() throws XPathException {
147:                if (declarationIsWritten)
148:                    return;
149:                declarationIsWritten = true;
150:                try {
151:                    indenting = "yes".equals(outputProperties
152:                            .getProperty(OutputKeys.INDENT));
153:                    String s = outputProperties
154:                            .getProperty(SaxonOutputKeys.INDENT_SPACES);
155:                    if (s != null) {
156:                        try {
157:                            indentSpaces = Integer.parseInt(s.trim());
158:                        } catch (NumberFormatException err) {
159:                        }
160:                    }
161:
162:                    String byteOrderMark = outputProperties
163:                            .getProperty(SaxonOutputKeys.BYTE_ORDER_MARK);
164:
165:                    if ("yes".equals(byteOrderMark)
166:                            && "UTF-8".equalsIgnoreCase(outputProperties
167:                                    .getProperty(OutputKeys.ENCODING))) {
168:                        // For UTF-16, Java outputs a BOM whether we like it or not
169:                        writer.write('\uFEFF');
170:                    }
171:
172:                    String omitXMLDeclaration = outputProperties
173:                            .getProperty(OutputKeys.OMIT_XML_DECLARATION);
174:                    if (omitXMLDeclaration == null) {
175:                        omitXMLDeclaration = "no";
176:                    }
177:
178:                    String version = outputProperties
179:                            .getProperty(OutputKeys.VERSION);
180:                    if (version == null) {
181:                        version = getConfiguration().getNameChecker()
182:                                .getXMLVersion();
183:                    } else {
184:                        if (!version.equals("1.0") && !version.equals("1.1")) {
185:                            DynamicError err = new DynamicError(
186:                                    "XML version must be 1.0 or 1.1");
187:                            err.setErrorCode("SESU0006");
188:                            throw err;
189:                        }
190:                        if (!version.equals("1.0")
191:                                && omitXMLDeclaration.equals("yes")
192:                                && outputProperties
193:                                        .getProperty(OutputKeys.DOCTYPE_SYSTEM) != null) {
194:                            DynamicError err = new DynamicError(
195:                                    "Values of 'version', 'omit-xml-declaration', and 'doctype-system' conflict");
196:                            err.setErrorCode("SEPM0009");
197:                            throw err;
198:                        }
199:                    }
200:
201:                    if (version.equals("1.0") && undeclareNamespaces) {
202:                        DynamicError err = new DynamicError(
203:                                "Cannot undeclare namespaces with XML version 1.0");
204:                        err.setErrorCode("SEPM0010");
205:                        throw err;
206:                    }
207:
208:                    String encoding = outputProperties
209:                            .getProperty(OutputKeys.ENCODING);
210:                    if (encoding == null || encoding.equalsIgnoreCase("utf8")) {
211:                        encoding = "UTF-8";
212:                    }
213:
214:                    String standalone = outputProperties
215:                            .getProperty(OutputKeys.STANDALONE);
216:                    if ("omit".equals(standalone)) {
217:                        standalone = null;
218:                    }
219:
220:                    if (standalone != null) {
221:                        requireWellFormed = true;
222:                        if (omitXMLDeclaration.equals("yes")) {
223:                            DynamicError err = new DynamicError(
224:                                    "Values of 'standalone' and 'omit-xml-declaration' conflict");
225:                            err.setErrorCode("SEPM0009");
226:                            throw err;
227:                        }
228:                    }
229:
230:                    if (omitXMLDeclaration.equals("no")) {
231:                        writer.write("<?xml version=\""
232:                                + version
233:                                + "\" "
234:                                + "encoding=\""
235:                                + encoding
236:                                + '\"'
237:                                + (standalone != null ? " standalone=\""
238:                                        + standalone + '\"' : "") + "?>");
239:                        // no longer write a newline character: it's wrong if the output is an
240:                        // external general parsed entity
241:                    }
242:                } catch (java.io.IOException err) {
243:                    throw new DynamicError(err);
244:                }
245:            }
246:
247:            /**
248:             * Output the document type declaration
249:             */
250:
251:            protected void writeDocType(String type, String systemId,
252:                    String publicId) throws XPathException {
253:                try {
254:                    if (declarationIsWritten && !indenting) {
255:                        // don't add a newline if indenting, because the indenter will already have done so
256:                        writer.write("\n");
257:                    }
258:                    writer.write("<!DOCTYPE " + type + '\n');
259:                    if (systemId != null && publicId == null) {
260:                        writer.write("  SYSTEM \"" + systemId + "\">\n");
261:                    } else if (systemId == null && publicId != null) { // handles the HTML case
262:                        writer.write("  PUBLIC \"" + publicId + "\">\n");
263:                    } else {
264:                        writer.write("  PUBLIC \"" + publicId + "\" \""
265:                                + systemId + "\">\n");
266:                    }
267:                } catch (java.io.IOException err) {
268:                    throw new DynamicError(err);
269:                }
270:            }
271:
272:            /**
273:             * End of the document. Close the output stream.
274:             */
275:
276:            public void close() throws XPathException {
277:                try {
278:                    if (writer != null) {
279:                        writer.flush();
280:                    }
281:                } catch (java.io.IOException err) {
282:                    throw new DynamicError(err);
283:                }
284:            }
285:
286:            /**
287:             * Start of an element. Output the start tag, escaping special characters.
288:             */
289:
290:            public void startElement(int nameCode, int typeCode,
291:                    int locationId, int properties) throws XPathException {
292:                if (empty) {
293:                    openDocument();
294:                } else if (requireWellFormed && elementStack.isEmpty()) {
295:                    DynamicError err = new DynamicError(
296:                            "When 'standalone' or 'doctype-system' is specified, the document must be well-formed; "
297:                                    + "but this document contains more than one top-level element");
298:                    err.setErrorCode("SEPM0004");
299:                    throw err;
300:                }
301:                String displayName = null;
302:
303:                // See if we've seen this name before
304:                if (nameCode < 2048) {
305:                    displayName = nameLookup[nameCode];
306:                }
307:
308:                // Otherwise, look it up in the namepool and check that it's encodable
309:                if (displayName == null) {
310:                    displayName = namePool.getDisplayName(nameCode);
311:                    if (nameCode < 2048) {
312:                        nameLookup[nameCode] = displayName;
313:                    }
314:                    int badchar = testCharacters(displayName);
315:                    if (badchar != 0) {
316:                        DynamicError err = new DynamicError(
317:                                "Element name contains a character (decimal + "
318:                                        + badchar
319:                                        + ") not available in the selected encoding");
320:                        err.setErrorCode("SERE0008");
321:                        throw err;
322:                    }
323:                }
324:
325:                elementStack.push(displayName);
326:                elementCode = nameCode;
327:
328:                try {
329:                    if (empty) {
330:                        String systemId = outputProperties
331:                                .getProperty(OutputKeys.DOCTYPE_SYSTEM);
332:                        String publicId = outputProperties
333:                                .getProperty(OutputKeys.DOCTYPE_PUBLIC);
334:                        if (systemId != null) {
335:                            requireWellFormed = true;
336:                            writeDocType(displayName, systemId, publicId);
337:                        }
338:                        empty = false;
339:                    }
340:                    if (openStartTag) {
341:                        closeStartTag();
342:                    }
343:                    writer.write('<');
344:                    writer.write(displayName);
345:                    openStartTag = true;
346:                    totalAttributeLength = 0;
347:
348:                } catch (java.io.IOException err) {
349:                    throw new DynamicError(err);
350:                }
351:            }
352:
353:            public void namespace(int namespaceCode, int properties)
354:                    throws XPathException {
355:                try {
356:                    String nsprefix = namePool
357:                            .getPrefixFromNamespaceCode(namespaceCode);
358:                    String nsuri = namePool
359:                            .getURIFromNamespaceCode(namespaceCode);
360:
361:                    int len = nsuri.length() + nsprefix.length() + 8;
362:                    String sep = " ";
363:                    if (indenting && (totalAttributeLength + len) > 80
364:                            && totalAttributeLength != 0) {
365:                        sep = getAttributeIndentString();
366:                    }
367:                    totalAttributeLength += len;
368:
369:                    if (nsprefix.equals("")) {
370:                        writer.write(sep);
371:                        writeAttribute(elementCode, "xmlns", nsuri, 0);
372:                    } else if (nsprefix.equals("xml")) {
373:                        return;
374:                    } else {
375:                        int badchar = testCharacters(nsprefix);
376:                        if (badchar != 0) {
377:                            DynamicError err = new DynamicError(
378:                                    "Namespace prefix contains a character (decimal + "
379:                                            + badchar
380:                                            + ") not available in the selected encoding");
381:                            err.setErrorCode("SERE0008");
382:                            throw err;
383:                        }
384:                        if (undeclareNamespaces || !nsuri.equals("")) {
385:                            writer.write(sep);
386:                            writeAttribute(elementCode, "xmlns:" + nsprefix,
387:                                    nsuri, 0);
388:                        }
389:                    }
390:                } catch (java.io.IOException err) {
391:                    throw new DynamicError(err);
392:                }
393:            }
394:
395:            public void attribute(int nameCode, int typeCode,
396:                    CharSequence value, int locationId, int properties)
397:                    throws XPathException {
398:                String displayName = null;
399:
400:                // See if we've seen this name before
401:                if (nameCode < 2048) {
402:                    displayName = nameLookup[nameCode];
403:                }
404:
405:                // Otherwise, look it up in the namepool and check that it's encodable
406:                if (displayName == null) {
407:                    displayName = namePool.getDisplayName(nameCode);
408:                    if (nameCode < 2048) {
409:                        nameLookup[nameCode] = displayName;
410:                    }
411:                    int badchar = testCharacters(displayName);
412:                    if (badchar != 0) {
413:                        DynamicError err = new DynamicError(
414:                                "Attribute name contains a character (decimal + "
415:                                        + badchar
416:                                        + ") not available in the selected encoding");
417:                        err.setErrorCode("SERE0008");
418:                        throw err;
419:                    }
420:                }
421:
422:                int len = displayName.length() + value.length() + 4;
423:                String sep = " ";
424:                if (indenting && (totalAttributeLength + len) > 80
425:                        && totalAttributeLength != 0) {
426:                    sep = getAttributeIndentString();
427:                }
428:                totalAttributeLength += len;
429:
430:                try {
431:                    writer.write(sep);
432:                    writeAttribute(elementCode, displayName, value, properties);
433:
434:                } catch (java.io.IOException err) {
435:                    throw new DynamicError(err);
436:                }
437:            }
438:
439:            private String getAttributeIndentString() {
440:                int indent = (elementStack.size() - 1) * indentSpaces
441:                        + ((String) elementStack.peek()).length() + 3;
442:                while (indent >= indentChars.length()) {
443:                    indentChars += "                     ";
444:                }
445:                return indentChars.substring(0, indent);
446:            }
447:
448:            public void startContent() throws XPathException {
449:                // don't add ">" to the start tag until we know whether the element has content
450:            }
451:
452:            public void closeStartTag() throws XPathException {
453:                try {
454:                    if (openStartTag) {
455:                        writer.write('>');
456:                        openStartTag = false;
457:                    }
458:                } catch (java.io.IOException err) {
459:                    throw new DynamicError(err);
460:                }
461:            }
462:
463:            /**
464:             * Close an empty element tag. (This is overridden in XHTMLEmitter).
465:             */
466:
467:            protected String emptyElementTagCloser(String displayName,
468:                    int nameCode) {
469:                return "/>";
470:            }
471:
472:            /**
473:             * Write attribute name=value pair.
474:             * @param elCode The element name is not used in this version of the
475:             * method, but is used in the HTML subclass.
476:             * @param attname The attribute name, which has already been validated to ensure
477:             * it can be written in this encoding
478:             * @param value The value of the attribute
479:             * @param properties Any special properties of the attribute
480:             */
481:
482:            protected void writeAttribute(int elCode, String attname,
483:                    CharSequence value, int properties) throws XPathException {
484:                try {
485:                    String val = value.toString();
486:                    writer.write(attname);
487:                    if ((properties & ReceiverOptions.NO_SPECIAL_CHARS) != 0) {
488:                        writer.write('=');
489:                        writer.write('"');
490:                        writer.write(val);
491:                        writer.write('"');
492:                    } else if ((properties & ReceiverOptions.USE_NULL_MARKERS) != 0) {
493:                        // null (0) characters will be used before and after any section of
494:                        // the value where escaping is to be disabled
495:                        writer.write('=');
496:                        char delimiter = (val.indexOf('"') >= 0 ? '\'' : '"');
497:                        writer.write(delimiter);
498:                        writeEscape(value, true);
499:                        writer.write(delimiter);
500:                    } else {
501:                        writer.write("=\"");
502:                        writeEscape(value, true);
503:                        writer.write('\"');
504:                    }
505:                } catch (java.io.IOException err) {
506:                    throw new DynamicError(err);
507:                }
508:            }
509:
510:            /**
511:             * Test that all characters in a name are supported in the target encoding.
512:             * @return zero if all the characters are available, or the value of the
513:             * first offending character if not
514:             */
515:
516:            protected int testCharacters(CharSequence chars)
517:                    throws XPathException {
518:                for (int i = 0; i < chars.length(); i++) {
519:                    char c = chars.charAt(i);
520:                    if (c > 127) {
521:                        if (XMLChar.isHighSurrogate(c)) {
522:                            int cc = XMLChar.supplemental(c, chars.charAt(++i));
523:                            if (!characterSet.inCharset(cc)) {
524:                                return cc;
525:                            }
526:                        } else if (!characterSet.inCharset(c)) {
527:                            return c;
528:                        }
529:                    }
530:                }
531:                return 0;
532:            }
533:
534:            /**
535:             * End of an element.
536:             */
537:
538:            public void endElement() throws XPathException {
539:                String displayName = (String) elementStack.pop();
540:                try {
541:                    if (openStartTag) {
542:                        writer.write(emptyElementTagCloser(displayName,
543:                                elementCode));
544:                        openStartTag = false;
545:                    } else {
546:                        writer.write("</");
547:                        writer.write(displayName);
548:                        writer.write('>');
549:                    }
550:                } catch (java.io.IOException err) {
551:                    throw new DynamicError(err);
552:                }
553:            }
554:
555:            /**
556:             * Character data.
557:             */
558:
559:            public void characters(CharSequence chars, int locationId,
560:                    int properties) throws XPathException {
561:                if (empty) {
562:                    openDocument();
563:                    if (!Whitespace.isWhite(chars)) {
564:                        if (requireWellFormed
565:                                || outputProperties
566:                                        .getProperty(OutputKeys.DOCTYPE_SYSTEM) != null) {
567:                            DynamicError err = new DynamicError(
568:                                    "When 'standalone' or 'doctype-system' is specified, the document must be well-formed; "
569:                                            + "but this document contains a top-level text node");
570:                            err.setErrorCode("SEPM0004");
571:                            throw err;
572:                        }
573:                    }
574:                }
575:
576:                if (requireWellFormed && elementStack.isEmpty()
577:                        && !Whitespace.isWhite(chars)) {
578:                    DynamicError err = new DynamicError(
579:                            "When 'standalone' or 'doctype-system' is specified, the document must be well-formed; "
580:                                    + "but this document contains a top-level text node");
581:                    err.setErrorCode("SEPM0004");
582:                    throw err;
583:                }
584:
585:                try {
586:                    if (openStartTag) {
587:                        closeStartTag();
588:                    }
589:
590:                    if ((properties & ReceiverOptions.NO_SPECIAL_CHARS) != 0) {
591:                        writeCharSequence(chars);
592:                    } else if ((properties & ReceiverOptions.DISABLE_ESCAPING) == 0) {
593:                        writeEscape(chars, false);
594:                    } else {
595:                        // disable-output-escaping="yes"
596:                        if (testCharacters(chars) == 0) {
597:                            writeCharSequence(chars);
598:                        } else {
599:                            // Recoverable error: using disable output escaping with characters
600:                            // that are not available in the target encoding
601:                            if (!warningIssued) {
602:                                try {
603:                                    getPipelineConfiguration()
604:                                            .getErrorListener()
605:                                            .warning(
606:                                                    new TransformerException(
607:                                                            "disable-output-escaping is ignored for characters "
608:                                                                    + "not available in the chosen encoding"));
609:                                } catch (TransformerException e) {
610:                                    throw DynamicError.makeDynamicError(e);
611:                                }
612:                                warningIssued = true;
613:                            }
614:                            writeEscape(chars, false);
615:                        }
616:                    }
617:                } catch (java.io.IOException err) {
618:                    throw new DynamicError(err);
619:                }
620:            }
621:
622:            /**
623:             * Write a CharSequence: various implementations
624:             */
625:
626:            public void writeCharSequence(CharSequence s)
627:                    throws java.io.IOException {
628:                if (s instanceof  String) {
629:                    writer.write((String) s);
630:                } else if (s instanceof  CharSlice) {
631:                    ((CharSlice) s).write(writer);
632:                } else if (s instanceof  FastStringBuffer) {
633:                    ((FastStringBuffer) s).write(writer);
634:                } else {
635:                    writer.write(s.toString());
636:                }
637:            }
638:
639:            /**
640:             * Handle a processing instruction.
641:             */
642:
643:            public void processingInstruction(String target, CharSequence data,
644:                    int locationId, int properties) throws XPathException {
645:                if (empty) {
646:                    openDocument();
647:                }
648:                try {
649:                    if (openStartTag) {
650:                        closeStartTag();
651:                    }
652:                    writer.write("<?" + target
653:                            + (data.length() > 0 ? ' ' + data.toString() : "")
654:                            + "?>");
655:                } catch (java.io.IOException err) {
656:                    throw new DynamicError(err);
657:                }
658:            }
659:
660:            /**
661:             * Write contents of array to current writer, after escaping special characters.
662:             * This method converts the XML special characters (such as < and &) into their
663:             * predefined entities.
664:             * @param chars The character sequence containing the string
665:             * @param inAttribute  Set to true if the text is in an attribute value
666:             */
667:
668:            protected void writeEscape(final CharSequence chars,
669:                    final boolean inAttribute) throws java.io.IOException,
670:                    XPathException {
671:                int segstart = 0;
672:                boolean disabled = false;
673:                final boolean[] specialChars = (inAttribute ? specialInAtt
674:                        : specialInText);
675:
676:                while (segstart < chars.length()) {
677:                    int i = segstart;
678:
679:                    // find a maximal sequence of "ordinary" characters
680:                    while (i < chars.length()) {
681:                        final char c = chars.charAt(i);
682:                        if (c < 127) {
683:                            if (specialChars[c]) {
684:                                break;
685:                            } else {
686:                                i++;
687:                            }
688:                        } else if (c < 160) {
689:                            break;
690:                        } else if (XMLChar.isHighSurrogate(c)) {
691:                            break;
692:                        } else if (!characterSet.inCharset(c)) {
693:                            break;
694:                        } else {
695:                            i++;
696:                        }
697:                    }
698:
699:                    // if this was the whole string write it out and exit
700:                    if (i >= chars.length()) {
701:                        if (segstart == 0) {
702:                            writeCharSequence(chars);
703:                        } else {
704:                            writeCharSequence(chars.subSequence(segstart, i));
705:                        }
706:                        return;
707:                    }
708:
709:                    // otherwise write out this sequence
710:                    if (i > segstart) {
711:                        writeCharSequence(chars.subSequence(segstart, i));
712:                    }
713:
714:                    // examine the special character that interrupted the scan
715:                    final char c = chars.charAt(i);
716:                    if (c == 0) {
717:                        // used to switch escaping on and off
718:                        disabled = !disabled;
719:                    } else if (disabled) {
720:                        writer.write(c);
721:                    } else if (c >= 127 && c < 160) {
722:                        // XML 1.1 requires these characters to be written as character references
723:                        outputCharacterReference(c);
724:                    } else if (c >= 160) {
725:                        if (XMLChar.isHighSurrogate(c)) {
726:                            char d = chars.charAt(++i);
727:                            int charval = XMLChar.supplemental(c, d);
728:                            if (characterSet.inCharset(charval)) {
729:                                writer.write(c);
730:                                writer.write(d);
731:                            } else {
732:                                outputCharacterReference(charval);
733:                            }
734:                        } else {
735:                            // process characters not available in the current encoding
736:                            outputCharacterReference(c);
737:                        }
738:
739:                    } else {
740:
741:                        // process special ASCII characters
742:
743:                        if (c == '<') {
744:                            writer.write("&lt;");
745:                        } else if (c == '>') {
746:                            writer.write("&gt;");
747:                        } else if (c == '&') {
748:                            writer.write("&amp;");
749:                        } else if (c == '\"') {
750:                            writer.write("&#34;");
751:                        } else if (c == '\n') {
752:                            writer.write("&#xA;");
753:                        } else if (c == '\r') {
754:                            writer.write("&#xD;");
755:                        } else if (c == '\t') {
756:                            writer.write("&#x9;");
757:                        } else {
758:                            // C0 control characters
759:                            outputCharacterReference(c);
760:                        }
761:                    }
762:                    segstart = ++i;
763:                }
764:            }
765:
766:            /**
767:             * Output a decimal or hexadecimal character reference
768:             */
769:
770:            private char[] charref = new char[10];
771:
772:            protected void outputCharacterReference(int charval)
773:                    throws java.io.IOException {
774:                if (preferHex) {
775:                    int o = 0;
776:                    charref[o++] = '&';
777:                    charref[o++] = '#';
778:                    charref[o++] = 'x';
779:                    String code = Integer.toHexString(charval);
780:                    int len = code.length();
781:                    for (int k = 0; k < len; k++) {
782:                        charref[o++] = code.charAt(k);
783:                    }
784:                    charref[o++] = ';';
785:                    writer.write(charref, 0, o);
786:                } else {
787:                    int o = 0;
788:                    charref[o++] = '&';
789:                    charref[o++] = '#';
790:                    String code = Integer.toString(charval);
791:                    int len = code.length();
792:                    for (int k = 0; k < len; k++) {
793:                        charref[o++] = code.charAt(k);
794:                    }
795:                    charref[o++] = ';';
796:                    writer.write(charref, 0, o);
797:                }
798:            }
799:
800:            /**
801:             * Handle a comment.
802:             */
803:
804:            public void comment(CharSequence chars, int locationId,
805:                    int properties) throws XPathException {
806:                if (empty) {
807:                    openDocument();
808:                }
809:                try {
810:                    if (openStartTag) {
811:                        closeStartTag();
812:                    }
813:                    writer.write("<!--");
814:                    writer.write(chars.toString());
815:                    writer.write("-->");
816:                } catch (java.io.IOException err) {
817:                    throw new DynamicError(err);
818:                }
819:            }
820:
821:            public static void main(String[] params) throws Exception {
822:                StreamResult iStreamResult = new StreamResult(
823:                        new CharArrayWriter());
824:                XMLEmitter iResult = new XMLEmitter();
825:                iResult.setStreamResult(iStreamResult);
826:
827:                StreamSource iSource = new StreamSource(new File(
828:                        "c:\\temp\\test.xml"));
829:
830:                System.setProperty("javax.xml.transform.TransformerFactory",
831:                        "net.sf.saxon.TransformerFactoryImpl");
832:                TransformerFactory iTfactory = TransformerFactory.newInstance();
833:                Templates iTemplates = iTfactory.newTemplates(new StreamSource(
834:                        new File("c:\\temp\\test.xsl")));
835:                iTemplates.newTransformer().transform(iSource, iResult);
836:
837:            }
838:
839:        }
840:
841:        //
842:        // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
843:        // you may not use this file except in compliance with the License. You may obtain a copy of the
844:        // License at http://www.mozilla.org/MPL/
845:        //
846:        // Software distributed under the License is distributed on an "AS IS" basis,
847:        // WITHOUT WARRANTY OF ANY KIND, either express or implied.
848:        // See the License for the specific language governing rights and limitations under the License.
849:        //
850:        // The Original Code is: all this file.
851:        //
852:        // The Initial Developer of the Original Code is Michael H. Kay.
853:        //
854:        // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
855:        //
856:        // Contributor(s): none.
857:        //
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.