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 NodeBuilder
s.
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
Document
s andElem
s. This package offers the eu.cdevreeze.yaidom.print.DocumentPrinter trait, as well as several implementations. Most of those implementations use theconvert
package to convert yaidomDocument
s 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)
convert
conversions. 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
DocumentPrinter
implementation does not use anyconvert
conversion. That isDocumentPrinterUsingSax
. It is likely the fastest of theDocumentPrinter
implementations, as well as the one using the least memory.The preferred
DocumentPrinter
for XML (not HTML) printing isDocumentPrinterUsingDomLS
, if memory usage is not an issue. ThisDocumentPrinter
implementation 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
convert
packages, and not the other way around.