|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object fi.karppinen.gnu.xml.util.XMLWriter
public class XMLWriter
This class is a SAX handler which writes all its input as a well formed XML or XHTML document. If driven using SAX2 events, this output may include a recreated document type declaration, subject to limitations of SAX (no internal subset exposed) or DOM (the important declarations, with their documentation, are discarded).
By default, text is generated "as-is", but some optional modes are supported. Pretty-printing is supported, to make life easier for people reading the output. XHTML (1.0) output has can be made particularly pretty. Canonical XML can also be generated, assuming the input is properly formed.
Some of the methods on this class are intended for applications to use directly, rather than as pure SAX2 event callbacks. Some of those methods access the JavaBeans properties (used to tweak output formats, for example canonicalization and pretty printing). Subclasses are expected to add new behaviors, not to modify current behavior, so many such methods are final.
The write*() methods may be slightly simpler for some applications to use than direct callbacks. For example, they support a simple policy for encoding data items as the content of a single element.
To reuse an XMLWriter you must provide it with a new Writer, since this handler closes the writer it was given as part of its endDocument() handling. (XML documents have an end of input, and the way to encode that on a stream is to close it.)
Note that any relative URIs in the source document, as found in entity and notation declarations, ought to have been fully resolved by the parser providing events to this handler. This means that the output text should only have fully resolved URIs, which may not be the desired behavior in cases where later binding is desired.
Note that due to SAX2 defaults, you may need to manually
ensure that the input events are XML-conformant with respect to namespace
prefixes and declarations. NSFilter
is
one solution to this problem, in the context of processing pipelines.
Something as simple as connecting this handler to a parser might not generate
the correct output. Another workaround is to ensure that the
namespace-prefixes feature is always set to true, if you're
hooking this directly up to some XMLReader implementation.
TextConsumer
Field Summary | |
---|---|
private boolean |
canonical
|
private int |
column
|
private static int |
CTX_ATTRIBUTE
|
private static int |
CTX_CONTENT
|
private static int |
CTX_ENTITY
|
private static int |
CTX_NAME
|
private static int |
CTX_UNPARSED
|
private int |
elementNestLevel
|
private int |
entityNestLevel
|
private static String |
eol
|
private ErrorHandler |
errHandler
|
private boolean |
expandingEntities
|
private boolean |
inCDATA
|
private boolean |
inDoctype
|
private boolean |
inEpilogue
|
private static int |
lineLength
|
private Locator |
locator
|
private boolean |
noWrap
|
private Writer |
out
|
private boolean |
prettyPrinting
|
private Stack<String> |
space
|
private boolean |
startedDoctype
|
private StringBuilder |
stringBuf
|
private boolean |
xhtml
|
Fields inherited from interface fi.karppinen.xml.XmlDeclarationHandler |
---|
XML_DECLARATION_HANDLER |
Constructor Summary | |
---|---|
XMLWriter()
Constructs this handler with System.out used to write SAX events using the UTF-8 encoding. |
|
XMLWriter(OutputStream out)
Constructs a handler which writes all input to the output stream in the UTF-8 encoding, and closes it when endDocument is called. |
|
XMLWriter(Writer writer)
Constructs a handler which writes all input to the writer, and then closes the writer when the document ends. |
Method Summary | |
---|---|
void |
attributeDecl(String eName,
String aName,
String type,
String mode,
String value)
SAX2 : called on attribute declarations |
void |
characters(char[] ch,
int start,
int length)
SAX1 : reports content characters |
void |
comment(char[] ch,
int start,
int length)
SAX2 : called when comments are parsed. |
private void |
doIndent()
|
void |
elementDecl(String name,
String model)
SAX2 : called on element declarations |
void |
endCDATA()
SAX2 : called after parsing CDATA characters |
void |
endDocument()
SAX1 : indicates the completion of a parse. |
void |
endDTD()
SAX2 : called after the doctype is parsed |
void |
endElement(String uri,
String localName,
String qName)
SAX2 : indicates the end of an element |
void |
endEntity(String name)
SAX2 : called after parsing a general entity in content |
void |
endPrefixMapping(String prefix)
SAX2 : ignored. |
private void |
escapeChars(char[] buf,
int off,
int len,
int code)
|
void |
externalEntityDecl(String name,
String publicId,
String systemId)
SAX2 : called on external entity declarations |
protected void |
fatal(String message,
Exception e)
Used internally and by subclasses, this encapsulates the logic involved in reporting fatal errors. |
void |
flush()
Flushes the output stream. |
void |
ignorableWhitespace(char[] ch,
int start,
int length)
SAX1 : reports ignorable whitespace |
private static boolean |
indentBefore(String tag)
|
void |
internalEntityDecl(String name,
String value)
SAX2 : called on internal entity declarations |
boolean |
isCanonical()
Returns value of flag controlling canonical output. |
private static boolean |
isEmptyElementTag(String tag)
|
boolean |
isExpandingEntities()
Returns true if the output will have no entity references; returns false (the default) otherwise. |
boolean |
isPrettyPrinting()
Returns value of flag controlling pretty printing. |
boolean |
isXhtml()
Returns true if the output attempts to echo the input following "transitional" XHTML rules and matching the "HTML Compatibility Guidelines" so that an HTML version 3 browser can read the output as HTML; returns false (the default) othewise. |
private void |
newline()
|
void |
notationDecl(String name,
String publicId,
String systemId)
SAX1 : called on notation declarations |
void |
processingInstruction(String target,
String data)
SAX1 : reports a PI. |
private void |
rawWrite(char c)
|
private void |
rawWrite(char[] buf,
int offset,
int length)
|
private void |
rawWrite(String s)
|
void |
setCanonical(boolean value)
Sets the output style to be canonicalized. |
void |
setDocumentLocator(Locator l)
SAX1 : provides parser status information |
void |
setErrorHandler(ErrorHandler handler)
Assigns the error handler to be used to present most fatal errors. |
void |
setExpandingEntities(boolean value)
Controls whether the output text contains references to entities (the default), or instead contains the expanded values of those entities. |
void |
setPrettyPrinting(boolean value)
Controls pretty-printing, which by default is not enabled (and currently is most useful for XHTML output). |
void |
setWriter(Writer writer)
Resets the handler to write a new text document. |
void |
setXhtml(boolean value)
Controls whether the output should attempt to follow the "transitional" XHTML rules so that it meets the "HTML Compatibility Guidelines" appendix in the XHTML specification. |
void |
skippedEntity(String name)
SAX1 : indicates a non-expanded entity reference |
private static boolean |
spaceBefore(String tag)
|
private static boolean |
spacePreserve(String tag)
|
void |
startCDATA()
SAX2 : called before parsing CDATA characters |
void |
startDocument()
SAX1 : indicates the beginning of a document parse. |
void |
startDTD(String name,
String publicId,
String systemId)
SAX2 : called when the doctype is partially parsed Note that this, like other doctype related calls, is ignored when XHTML is in use. |
void |
startElement(String uri,
String localName,
String qName,
Attributes atts)
SAX2 : indicates the start of an element. |
void |
startEntity(String name)
SAX2 : called before parsing a general entity in content |
void |
startPrefixMapping(String prefix,
String uri)
SAX2 : ignored. |
void |
unparsedEntityDecl(String name,
String publicId,
String systemId,
String notationName)
SAX1 : called on unparsed entity declarations |
void |
write(String data)
Writes the string as if characters() had been called on the contents of the string. |
void |
writeElement(String uri,
String localName,
String qName,
Attributes atts,
int content)
Writes an element that has content consisting of a single integer, encoded as a decimal string. |
void |
writeElement(String uri,
String localName,
String qName,
Attributes atts,
String content)
Writes an element that has content consisting of a single string. |
void |
writeEmptyElement(String uri,
String localName,
String qName,
Attributes atts)
Writes an empty element. |
private void |
writeQuotedValue(String value,
int code)
|
private void |
writeStartTag(String name,
Attributes atts,
boolean isEmpty)
|
void |
xmlDecl(String version,
String encoding,
String standalone)
Receive a notification of the XML declaration. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
private static final int CTX_ENTITY
private static final int CTX_ATTRIBUTE
private static final int CTX_CONTENT
private static final int CTX_UNPARSED
private static final int CTX_NAME
private Writer out
private boolean inCDATA
private int elementNestLevel
private static final String eol
private StringBuilder stringBuf
private Locator locator
private ErrorHandler errHandler
private boolean expandingEntities
private int entityNestLevel
private boolean xhtml
private boolean startedDoctype
private boolean canonical
private boolean inDoctype
private boolean inEpilogue
private boolean prettyPrinting
private int column
private boolean noWrap
private Stack<String> space
private static final int lineLength
Constructor Detail |
---|
public XMLWriter() throws IOException
IOException
public XMLWriter(OutputStream out) throws IOException
IOException
public XMLWriter(Writer writer)
See the description of the constructor which takes an encoding name for imporant information about selection of encodings.
writer
- XML text is written to this writer.Method Detail |
---|
public final void setWriter(Writer writer)
writer
- XML text is written to this writer.
IllegalStateException
- if the current document hasn't yet ended (with
endDocument()
)public void setErrorHandler(ErrorHandler handler)
protected void fatal(String message, Exception e) throws SAXException
SAXException
public final void setXhtml(boolean value)
When this option is enabled, it is the caller's responsibility to ensure that the input is otherwise valid as XHTML. Things to be careful of in all cases, as described in the appendix referenced above, include:
Additionally, some of the oldest browsers have additional quirks, to address with guidelines such as:
Also, some characteristics of the resulting output may be a function of whether the document is later given a MIME content type of text/html rather than one indicating XML ( application/xml or text/xml). Worse, some browsers ignore MIME content types and prefer to rely URI name suffixes -- so an "index.xml" could always be XML, never XHTML, no matter its MIME type.
public final boolean isXhtml()
public final void setExpandingEntities(boolean value)
public final boolean isExpandingEntities()
public final void setPrettyPrinting(boolean value)
At this writing, structural indentation and line wrapping are enabled when pretty printing is enabled and the xml:space attribute has the value default (its other legal value is preserve, as defined in the XML specification). The three XHTML element types which use another value are recognized by their names (namespaces are ignored).
Also, for the record, the "pretty" aspect of printing here is more to provide basic structure on outputs that would otherwise risk being a single long line of text. For now, expect the structure to be ragged ... unless you'd like to submit a patch to make this be more strictly formatted!
IllegalStateException
- thrown if this method is invoked after output has begun.public final boolean isPrettyPrinting()
public final void setCanonical(boolean value)
Note that fragments of XML documents, as specified by an XPath node set, may be canonicalized. In such cases, elements may need some fixup (for xml:* attributes and application-specific context).
IllegalArgumentException
- if the output encoding is anything other than UTF-8.public final boolean isCanonical()
public final void flush() throws IOException
IOException
public final void write(String data) throws SAXException
SAXException
public void writeElement(String uri, String localName, String qName, Attributes atts, String content) throws SAXException
SAXException
writeEmptyElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
,
startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
public void writeElement(String uri, String localName, String qName, Attributes atts, int content) throws SAXException
SAXException
writeEmptyElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
,
startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
public final void setDocumentLocator(Locator l)
setDocumentLocator
in interface ContentHandler
public void startDocument() throws SAXException
startDocument
in interface ContentHandler
SAXException
public void endDocument() throws SAXException
endDocument
in interface ContentHandler
SAXException
private static final boolean isEmptyElementTag(String tag)
private static boolean indentBefore(String tag)
private static boolean spaceBefore(String tag)
private static boolean spacePreserve(String tag)
public final void startPrefixMapping(String prefix, String uri)
startPrefixMapping
in interface ContentHandler
public final void endPrefixMapping(String prefix)
endPrefixMapping
in interface ContentHandler
private void writeStartTag(String name, Attributes atts, boolean isEmpty) throws SAXException, IOException
SAXException
IOException
public final void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException
startElement
in interface ContentHandler
SAXException
public void writeEmptyElement(String uri, String localName, String qName, Attributes atts) throws SAXException
SAXException
startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
public final void endElement(String uri, String localName, String qName) throws SAXException
endElement
in interface ContentHandler
SAXException
public final void characters(char[] ch, int start, int length) throws SAXException
characters
in interface ContentHandler
SAXException
public final void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
ignorableWhitespace
in interface ContentHandler
SAXException
public final void processingInstruction(String target, String data) throws SAXException
processingInstruction
in interface ContentHandler
SAXException
public void skippedEntity(String name) throws SAXException
skippedEntity
in interface ContentHandler
SAXException
public final void startCDATA() throws SAXException
startCDATA
in interface LexicalHandler
SAXException
public final void endCDATA() throws SAXException
endCDATA
in interface LexicalHandler
SAXException
public final void startDTD(String name, String publicId, String systemId) throws SAXException
startDTD
in interface LexicalHandler
SAXException
public final void endDTD() throws SAXException
endDTD
in interface LexicalHandler
SAXException
public final void startEntity(String name) throws SAXException
startEntity
in interface LexicalHandler
SAXException
public final void endEntity(String name) throws SAXException
endEntity
in interface LexicalHandler
SAXException
public final void comment(char[] ch, int start, int length) throws SAXException
comment
in interface LexicalHandler
SAXException
public final void notationDecl(String name, String publicId, String systemId) throws SAXException
notationDecl
in interface DTDHandler
SAXException
public final void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException
unparsedEntityDecl
in interface DTDHandler
SAXException
public final void attributeDecl(String eName, String aName, String type, String mode, String value) throws SAXException
attributeDecl
in interface DeclHandler
SAXException
public final void elementDecl(String name, String model) throws SAXException
elementDecl
in interface DeclHandler
SAXException
public final void externalEntityDecl(String name, String publicId, String systemId) throws SAXException
externalEntityDecl
in interface DeclHandler
SAXException
public final void internalEntityDecl(String name, String value) throws SAXException
internalEntityDecl
in interface DeclHandler
SAXException
public void xmlDecl(String version, String encoding, String standalone) throws SAXException
XmlDeclarationHandler
xmlDecl
in interface XmlDeclarationHandler
version
- the XML version numberencoding
- the encoding
pseudo-attribute or null
if not presentstandalone
- the standalone
pseudo-attribute or null
if not present
SAXException
- any SAX exception, possibly wrapping another exceptionXmlDeclarationHandler.xmlDecl(java.lang.String, java.lang.String, java.lang.String)
private void writeQuotedValue(String value, int code) throws SAXException, IOException
SAXException
IOException
private void escapeChars(char[] buf, int off, int len, int code) throws SAXException, IOException
SAXException
IOException
private void newline() throws SAXException, IOException
SAXException
IOException
private void doIndent() throws SAXException, IOException
SAXException
IOException
private void rawWrite(char c) throws IOException
IOException
private void rawWrite(String s) throws SAXException, IOException
SAXException
IOException
private void rawWrite(char[] buf, int offset, int length) throws SAXException, IOException
SAXException
IOException
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |