Partial DocumentPrinter implementation.
eu.cdevreeze.yaidom.simple.Document printer (to the XML as a String or byte array).
eu.cdevreeze.yaidom.simple.Document printer (to the XML as a String or byte array). This trait is purely abstract.
Implementing classes deal with the details of printing yaidom documents as XML strings or byte arrays. The eu.cdevreeze.yaidom.simple package itself is agnostic of those details.
Typical implementations use DOM or StAX, but make them easier to use in the tradition of the "template" classes
of the Spring framework. That is, resource management is done as much as possible by the DocumentPrinter,
typical usage is easy, and complex scenarios are still possible. The idea is that the document printer is configured once, and
that it should be re-usable multiple times.
Although DocumentPrinter instances should be re-usable multiple times, implementing classes are encouraged to indicate
to what extent re-use of a DocumentPrinter instance is indeed supported (single-threaded, or even multi-threaded).
DOM-based Document printer.
DOM-based Document printer.
It may be the case that the DocumentPrinter does not indent. See bug http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6296446.
This problem appears especially when creating a Document from scratch, using NodeBuilders.
A possible (implementation-specific!) workaround is to create the DocumentPrinter as follows:
val documentBuilderFactory: DocumentBuilderFactory = DocumentBuilderFactory.newInstance val transformerFactory: TransformerFactory = TransformerFactory.newInstance transformerFactory.setAttribute("indent-number", java.lang.Integer.valueOf(2)) val documentPrinter = DocumentPrinterUsingDom.newInstance(documentBuilderFactory, transformerFactory)
If more flexibility is needed in configuring the DocumentPrinter than offered by this class, consider
writing a wrapper DocumentPrinter which wraps a DocumentPrinterUsingDom, but adapts the print method.
This would make it possible to adapt the conversion from a yaidom Document to DOM Document, for example.
A DocumentPrinterUsingDom instance can be re-used multiple times, from the same thread.
If the DocumentBuilderFactory and TransformerFactory are thread-safe, it can even be re-used from multiple threads.
Typically a DocumentBuilderFactory or TransformerFactory cannot be trusted to be thread-safe, however. In a web application,
one (safe) way to deal with that is to use one DocumentBuilderFactory and TransformerFactory instance per request.
In order to serialize a yaidom Document as HTML (which could have been parsed using the TagSoup library), a "transformer creator" can be coded as follows:
val trCreator = { (tf: TransformerFactory) => val t = tf.newTransformer t.setOutputProperty(OutputKeys.METHOD, "html") t }
This "transformer creator" is then passed as one of the arguments during DocumentPrinter construction.
Using such a DocumentPrinter configured for "HTML serialization", the serialized HTML is hopefully better understood
by browsers than would have been the case with a DocumentPrinter configured for "XML serialization".
For example, script tags (with empty content) are typically not written as self-closing tags in the first case,
whereas they are in the second case.
If a DocumentPrinter is not explicitly configured for either "HTML or XML serialization", it may still be the case
that HTML is serialized as HTML, depending on the TrAX implementation. Yet it is likely that in that case other elements
than the document element would be serialized as XML instead of HTML. After all, (immutable) yaidom elements do not know about
their ancestry.
DOM-LS-based Document printer.
DOM-LS-based Document printer.
To pretty-print a Document, create a DocumentPrinterUsingDomLS instance as follows:
val printer = DocumentPrinterUsingDomLS.newInstance() withSerializerCreator { domImpl => val writer = domImpl.createLSSerializer() writer.getDomConfig.setParameter("format-pretty-print", java.lang.Boolean.TRUE) writer }
If more flexibility is needed in configuring the DocumentPrinter than offered by this class, consider
writing a wrapper DocumentPrinter which wraps a DocumentPrinterUsingDomLS, but adapts the print method.
This would make it possible to adapt the serialization, for example.
A DocumentPrinterUsingDomLS instance can be re-used multiple times, from the same thread.
If the DocumentBuilderFactory and DOMImplementationLS are thread-safe, it can even be re-used from multiple threads.
Typically a DocumentBuilderFactory or DOMImplementationLS cannot be trusted to be thread-safe, however. In a web application,
one (safe) way to deal with that is to use one DocumentBuilderFactory and DOMImplementationLS instance per request.
SAX-based Document printer.
SAX-based Document printer. It should be the fastest of the DocumentPrinter implementations, and use the least memory.
See http://blogger.ziesemer.com/2007/06/xml-generation-in-java.html#SAXMethod.
If more flexibility is needed in configuring the DocumentPrinter than offered by this class, consider
writing a wrapper DocumentPrinter which wraps a DocumentPrinterUsingSax, but adapts the print method.
This would make it possible to adapt the generation of SAX events, for example.
A DocumentPrinterUsingSax instance can be re-used multiple times, from the same thread.
If the SAXTransformerFactory is thread-safe, it can even be re-used from multiple threads.
Typically a SAXTransformerFactory cannot be trusted to be thread-safe, however. In a web application,
one (safe) way to deal with that is to use one SAXTransformerFactory instance per request.
StAX-based Document printer.
StAX-based Document printer.
Note: this XML printer does not pretty-print!
If more flexibility is needed in configuring the DocumentPrinter than offered by this class, consider
writing a wrapper DocumentPrinter which wraps a DocumentPrinterUsingStax, but adapts the print method.
This would make it possible to adapt the conversion from a yaidom Document to StAX events, for example.
A DocumentPrinterUsingStax instance can be re-used multiple times, from the same thread.
If the XMLEventFactory and XMLOutputFactory are thread-safe, it can even be re-used from multiple threads.
Typically these objects cannot be trusted to be thread-safe, however. In a web application,
one (safe) way to deal with that is to use one XMLEventFactory and XMLOutputFactory instance per request.
Thread-local DocumentPrinter.
Thread-local DocumentPrinter. This class exists because typical JAXP factory objects (DocumentBuilderFactory etc.) are not thread-safe, but still expensive to create. Using this DocumentPrinter facade backed by a thread local DocumentPrinter, we can create a ThreadLocalDocumentPrinter once, and re-use it all the time without having to worry about thread-safety issues.
Note that each ThreadLocalDocumentPrinter instance (!) has its own thread-local document printer. Typically it makes no sense to have more than one ThreadLocalDocumentPrinter instance in one application. In a Spring application, for example, a single instance of a ThreadLocalDocumentPrinter can be configured.
Support for "printing" yaidom
Documents andElems. This package offers the eu.cdevreeze.yaidom.print.DocumentPrinter trait, as well as several implementations. Most of those implementations use theconvertpackage to convert yaidomDocuments to JAXP artifacts, and all use JAXP (DOM, SAX or StAX).For example:
This example chose a SAX-based implementation, and used the default configuration of that document printer.
Having several different fully configurable JAXP-based implementations shows that yaidom is pessimistic about the transparency of parsing and printing XML. It also shows that yaidom is optimistic about the available (heap) memory and processing power, because of the 2 separated steps of JAXP parsing/printing and (in-memory)
convertconversions. Using JAXP means that escaping of characters is something that JAXP deals with, and that's definitely better than trying to do it yourself.One
DocumentPrinterimplementation does not use anyconvertconversion. That isDocumentPrinterUsingSax. It is likely the fastest of theDocumentPrinterimplementations, as well as the one using the least memory.The preferred
DocumentPrinterfor XML (not HTML) printing isDocumentPrinterUsingDomLS, if memory usage is not an issue. ThisDocumentPrinterimplementation is best integrated with DOM, and is highly configurable, although DOM LS configuration is somewhat involved.This package depends on the eu.cdevreeze.yaidom.core, eu.cdevreeze.yaidom.queryapi, eu.cdevreeze.yaidom.simple and eu.cdevreeze.yaidom.convert packages, and not the other way around.