org.znerd.xmlenc
Class XMLOutputter

java.lang.Object
  |
  +--org.znerd.xmlenc.XMLOutputter
All Implemented Interfaces:
XMLOutputterStates

public class XMLOutputter
extends Object
implements XMLOutputterStates

Stream-based XML outputter. Instances of this class are able to write XML output to Writers.

Standards compliance

This class is intended to produce output that conforms to the XML 1.0 Specification. However, not all applicable restrictions are validated. For example, it is currently not checked if names contain characters that are invalid within a Name production.

Furthermore, not all possible XML documents can be produced. The following limitations apply:

Supported encodings

The following encodings are supported:

Multi-threading

This class is not thread-safe.

Exceptions

Note that all methods check the state first and then check the arguments. This means that if the state is incorrect and the arguments are incorrect, then an IllegalStateException will be thrown.

If any of the writing methods generates an IOException, then the state will be set to XMLOutputterStates.ERROR_STATE and no more output can be performed.

State transitions

Initially the state of an XMLOutputter is XMLOutputterStates.BEFORE_XML_DECLARATION if it is initialized with a Writer. Otherwise it is initially in the state XMLOutputterStates.UNINITIALIZED. The state is changed by calls to either the output methods or to setState(XMLOutputter.State,String[]). The latter should rarely be used.

The following table defines what the state transitions are when one of the output methods is called in a certain state. Horizontally are the current states, vertically the output methods. The cells self contain the new state.

S0 S1 S2 S3 S4 S5
declaration() S1 ISE ISE ISE ISE ISE
dtd(String,String,String) S2 S2 ISE ISE ISE ISE
startTag(String) S3 S3 S3 S3 S3 ISE
attribute(String,String) ISE ISE ISE S3 ISE ISE
endTag() ISE ISE ISE S4/S5 S4/S5 ISE
pcdata(String) ISE ISE ISE S4 S4 ISE
pcdata(char[],int,int) ISE ISE ISE S4 S4 ISE
whitespace(String) S1 S1 S4 S4 S4 S5
whitespace(char[],int,int) S1 S1 S4 S4 S4 S5
comment(String) S1 S1 S4 S4 S4 S5
pi(String,String) S1 S1 S4 S4 S4 S5
cdata(String) ISE ISE ISE S4 S4 ISE
close() ISE ISE ISE S5 S5 S5

List of states as used in the table:

Performance hints

It is usually a good idea to let XMLOutputter instances write to buffered Writers. This typically improves performance on large documents or relatively slow or blocking output streams.

Instances of this class can be cached in a pool to reduce object creations. Call reset() (with no arguments) when storing an instance in the pool. Use reset(Writer,String) (with 2 arguments) to re-initialize the instance after fetching it from the pool.

Since:
xmlenc 0.19
Version:
$Revision: 1.89 $ $Date: 2003/04/25 13:10:31 $
Author:
Ernst de Haan (znerd@FreeBSD.org)

Inner Class Summary
static class XMLOutputter.State
          State of the outputter.
 
Fields inherited from interface org.znerd.xmlenc.XMLOutputterStates
AFTER_ROOT_ELEMENT, BEFORE_DTD_DECLARATION, BEFORE_ROOT_ELEMENT, BEFORE_XML_DECLARATION, ERROR_STATE, START_TAG_OPEN, UNINITIALIZED, WITHIN_ELEMENT
 
Constructor Summary
XMLOutputter()
          Constructs a new XMLOutputter.
XMLOutputter(Writer out, String encoding)
          Constructs a new XMLOutputter for the specified Writer and encoding.
 
Method Summary
 void attribute(String name, String value)
          Adds an attribute to the current element.
 void cdata(String text)
          Writes a CDATA section.
 void close()
          Closes all open elements.
 void comment(String text)
          Writes the specified comment.
 void declaration()
          Writes the XML declaration.
 void dtd(String name, String publicID, String systemID)
          Writes a document type declaration.
 void endTag()
          Writes an element end tag.
 String[] getElementStack()
          Returns a copy of the element stack.
 int getElementStackCapacity()
          Returns the current capacity for the stack of open elements.
 int getElementStackSize()
          Returns the current depth of open elements.
 String getEncoding()
          Returns the encoding of this outputter.
 char getQuotationMark()
          Gets the quotation mark character.
 XMLOutputter.State getState()
          Returns the current state of this outputter.
static String getVersion()
          Returns the version of the xmlenc library.
 Writer getWriter()
          Returns the output stream this outputter uses.
 boolean isEscaping()
          Checks if escaping is currently enabled.
 void pcdata(char[] ch, int start, int length)
          Writes the specified character array as PCDATA.
 void pcdata(String text)
          Writes the specified String as PCDATA.
 void pi(String target, String instruction)
          Writes a processing instruction.
 void reset()
          Resets this XMLOutputter.
 void reset(Writer out, String encoding)
          Resets this XMLOutputter and configures it for the specified output stream and encoding.
 void setElementStackCapacity(int newCapacity)
          Sets the capacity for the stack of open elements.
 void setEscaping(boolean escapeAmpersands)
          Sets if ampersands should be escaped.
 void setQuotationMark(char c)
          Sets the quotation mark character to use.
 void setState(XMLOutputter.State newState, String[] newElementStack)
          Sets the state of this outputter.
 void startTag(String type)
          Writes an element start tag.
 void whitespace(char[] ch, int start, int length)
          Writes text from the specified character array as ignorable whitespace.
 void whitespace(String whitespace)
          Writes the specified ignorable whitespace.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

XMLOutputter

public XMLOutputter()
Constructs a new XMLOutputter. This sets the state to XMLOutputterStates.UNINITIALIZED.

XMLOutputter

public XMLOutputter(Writer out,
                    String encoding)
             throws IllegalStateException,
                    IllegalArgumentException,
                    UnsupportedEncodingException
Constructs a new XMLOutputter for the specified Writer and encoding. This sets the state to XMLOutputterStates.BEFORE_XML_DECLARATION.

The encoding will be stored exactly as passed, leaving the case intact.

Parameters:
out - the output stream to write to, not null.
encoding - the encoding, not null.
Throws:
IllegalStateException - if getState() != UNINITIALIZED && getState() != AFTER_ROOT_ELEMENT && getState() != ERROR_STATE.
IllegalArgumentException - if out == null || encoding == null.
UnsupportedEncodingException - if the specified encoding is not supported.
Method Detail

getVersion

public static final String getVersion()
Returns the version of the xmlenc library.
Returns:
the version of this library, for example "0.29", never null.
Since:
xmlenc 0.24

getWriter

public final Writer getWriter()
Returns the output stream this outputter uses.
Returns:
the output stream of this encoding, only null if and only if the state is XMLOutputterStates.UNINITIALIZED.

getEncoding

public final String getEncoding()
Returns the encoding of this outputter.
Returns:
the encoding of this encoding, only null if and only if the state is XMLOutputterStates.UNINITIALIZED.

reset

public void reset()
Resets this XMLOutputter. The Writer and the encoding will be set to null, the element stack will be cleared and the state will be set to XMLOutputterStates.UNINITIALIZED.

reset

public final void reset(Writer out,
                        String encoding)
                 throws IllegalArgumentException,
                        UnsupportedEncodingException
Resets this XMLOutputter and configures it for the specified output stream and encoding. This resets the state to XMLOutputterStates.BEFORE_XML_DECLARATION and clears the stack of open elements.
Parameters:
out - the output stream to write to, not null.
encoding - the encoding, not null.
Throws:
IllegalArgumentException - if out == null || encoding == null.
UnsupportedEncodingException - if the specified encoding is not supported.

setState

public final void setState(XMLOutputter.State newState,
                           String[] newElementStack)
                    throws IllegalArgumentException
Sets the state of this outputter. Normally, it is not necessary to call this method.

Caution: This method can be used to let this class generate invalid XML.

Parameters:
newState - the new state, not null.
newElementStack - the new element stack, if newState == START_TAG_OPEN || newState == WITHIN_ELEMENT then it should be non-null and containing no null elements, otherwise it must be null.
Throws:
IllegalArgumentException - if newState == null || (newState == START_TAG_OPEN && newElementStack == null) || (newState == WITHIN_ELEMENT && newElementStack == null) || (newState != START_TAG_OPEN && newState != WITHIN_ELEMENT && newElementStack != null) || newElementStack[n] == null (where 0 <= n < newElementStack.length).
Since:
xmlenc 0.22

getState

public final XMLOutputter.State getState()
Returns the current state of this outputter.
Returns:
the current state, cannot be null.

isEscaping

public final boolean isEscaping()
Checks if escaping is currently enabled. If escaping is enabled, then all ampersand characters ('&') are replaced by the character entity reference "&amp;". This affects PCDATA string printing (pcdata(String) and pcdata(char[],int,int)) and attribute value printing (attribute(String,String)).
Returns:
true if escaping is enabled, false otherwise.

setEscaping

public final void setEscaping(boolean escapeAmpersands)
Sets if ampersands should be escaped. This affects PCDATA string printing (pcdata(String) and pcdata(char[],int,int)) and attribute value printing (attribute(String,String)).

If ampersands are not escaped, then entity references can be printed.

Parameters:
escapeAmpersands - true if ampersands should be escaped, false otherwise.
Since:
xmlenc 0.24

getElementStack

public final String[] getElementStack()
Returns a copy of the element stack. The returned array will be a new array. The size of the array will be equal to the element stack size (see getElementStackSize().
Returns:
a newly constructed array that contains all the element types currently on the element stack, or null if there are no elements on the stack.
Since:
xmlenc 0.22

getElementStackSize

public final int getElementStackSize()
Returns the current depth of open elements.
Returns:
the open element depth, always >= 0.
Since:
xmlenc 0.22

getElementStackCapacity

public final int getElementStackCapacity()
Returns the current capacity for the stack of open elements.
Returns:
the open element stack capacity, always >= getElementStackSize().
Since:
xmlenc 0.28

setElementStackCapacity

public final void setElementStackCapacity(int newCapacity)
                                   throws IllegalArgumentException,
                                          OutOfMemoryError
Sets the capacity for the stack of open elements. The new capacity must at least allow the stack to contain the current open elements.
Parameters:
newCapacity - the new capacity, >= getElementStackSize().
Throws:
IllegalArgumentException - if newCapacity < getElementStackSize().
OutOfMemoryError - if a new array cannot be allocated; this object will still be usable, but the capacity will remain unchanged.

setQuotationMark

public final void setQuotationMark(char c)
                            throws IllegalArgumentException
Sets the quotation mark character to use. This character is printed before and after an attribute value. It can be either the single or the double quote character.

The default quotation mark character is '"'.

Parameters:
c - the character to put around attribute values, either '\'' or '"'.
Throws:
IllegalArgumentException - if c != '\'' && c != '"'.

getQuotationMark

public final char getQuotationMark()
Gets the quotation mark character. This character is used to mark the start and end of an attribute value.

The default quotation mark character is '"'.

Returns:
the character to put around attribute values, either '\'' or '"'.

declaration

public final void declaration()
                       throws IllegalStateException,
                              IOException
Writes the XML declaration. This method always prints the name of the encoding. The case of the encoding is as it was specified during initialization (or re-initialization).

If the encoding is set to "ISO-8859-1", then this method will produce the following output:

<?xml version="1.0" encoding="ISO-8859-1"?gt;
Throws:
IllegalStateException - if getState() != BEFORE_XML_DECLARATION.
IOException - if an I/O error occurs; this will set the state to XMLOutputterStates.ERROR_STATE.

dtd

public final void dtd(String name,
                      String publicID,
                      String systemID)
               throws IllegalStateException,
                      IllegalArgumentException,
                      IOException
Writes a document type declaration.

An external subset can be specified using either a system identifier (alone), or using both a public identifier and a system identifier. It can never be specified using a public identifier alone.

For example, for XHTML 1.0 the public identifier is:

-//W3C//DTD XHTML 1.0 Transitional//EN

while the system identifier is:

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd

The output is typically similar to this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
or alternatively, if only the system identifier is specified:
<!DOCTYPE html SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Parameters:
name - the name of the document type, not null.
publicID - the public identifier, can be null.
systemID - the system identifier, can be null, but otherwise it should be a properly formatted URL, see section 4.2.2 External Entities in the XML 1.0 Specification.
Throws:
IllegalStateException - if getState() != BEFORE_XML_DECLARATION && getState() != BEFORE_DTD_DECLARATION.
IllegalArgumentException - if name == null || (publicID != null && systemID == null).
IOException - if an I/O error occurs; this will set the state to XMLOutputterStates.ERROR_STATE.

startTag

public final void startTag(String type)
                    throws IllegalStateException,
                           IllegalArgumentException,
                           IOException
Writes an element start tag. The element type name will be stored in the internal element stack. If necessary, the capacity of this stack will be extended.
Parameters:
type - the type of the tag to start, not null.
Throws:
IllegalStateException - if getState() == UNINITIALIZED || getState() == AFTER_ROOT_ELEMENT || getState() == ERROR_STATE.
IllegalArgumentException - if type == null.
IOException - if an I/O error occurs; this will set the state to XMLOutputterStates.ERROR_STATE.

attribute

public final void attribute(String name,
                            String value)
                     throws IllegalStateException,
                            IllegalArgumentException,
                            IOException
Adds an attribute to the current element. There must currently be an open element.

The attribute value is surrounded by single quotes.

Parameters:
name - the name of the attribute, not null.
value - the value of the attribute, not null.
Throws:
IllegalStateException - if getState() != XMLOutputterStates.START_TAG_OPEN.
IllegalArgumentException - if name == null || value == null.
IOException - if an I/O error occurs; this will set the state to XMLOutputterStates.ERROR_STATE.

endTag

public final void endTag()
                  throws IllegalStateException,
                         IOException
Writes an element end tag.
Throws:
IllegalStateException - if getState() != START_TAG_OPEN && getState() != WITHIN_ELEMENT
IOException - if an I/O error occurs; this will set the state to XMLOutputterStates.ERROR_STATE.

pcdata

public final void pcdata(String text)
                  throws IllegalStateException,
                         IllegalArgumentException,
                         IOException
Writes the specified String as PCDATA.
Parameters:
text - the PCDATA text to be written, not null.
Throws:
IllegalStateException - if getState() != START_TAG_OPEN && getState() != WITHIN_ELEMENT
IllegalArgumentException - if text == null.
IOException - if an I/O error occurs; this will set the state to XMLOutputterStates.ERROR_STATE.

pcdata

public final void pcdata(char[] ch,
                         int start,
                         int length)
                  throws IllegalStateException,
                         IllegalArgumentException,
                         IndexOutOfBoundsException,
                         IOException
Writes the specified character array as PCDATA.
Parameters:
ch - the character array containing the text to be written, not null.
start - the start index in the array, must be >= 0 and it must be < ch.length.
length - the number of characters to read from the array, must be > 0.
Throws:
IllegalStateException - if getState() != START_TAG_OPEN && getState() != WITHIN_ELEMENT
IllegalArgumentException - if ch == null || start < 0 || start >= ch.length || length < 0.
IndexOutOfBoundsException - if start + length > ch.length.
IOException - if an I/O error occurs; this will set the state to XMLOutputterStates.ERROR_STATE.

whitespace

public final void whitespace(String whitespace)
                      throws IllegalStateException,
                             IllegalArgumentException,
                             IOException
Writes the specified ignorable whitespace. Ignorable whitespace may be written anywhere in XML output stream, except above the XML declaration.

This method does not check if the string actually contains whitespace.

If the state equals XMLOutputterStates.BEFORE_XML_DECLARATION, then it will be set to XMLOutputterStates.BEFORE_DTD_DECLARATION, otherwise if the state is XMLOutputterStates.START_TAG_OPEN then it will be set to XMLOutputterStates.WITHIN_ELEMENT, otherwise the state will not be changed.

Parameters:
whitespace - the ignorable whitespace to be written, not null.
Throws:
IllegalStateException - if getState() == ERROR_STATE.
IllegalArgumentException - if whitespace == null.
IOException - if an I/O error occurs; this will set the state to XMLOutputterStates.ERROR_STATE.

whitespace

public final void whitespace(char[] ch,
                             int start,
                             int length)
                      throws IllegalStateException,
                             IllegalArgumentException,
                             IndexOutOfBoundsException,
                             IOException
Writes text from the specified character array as ignorable whitespace. Ignorable whitespace may be written anywhere in XML output stream, except above the XML declaration.

This method does not check if the string actually contains whitespace.

If the state equals XMLOutputterStates.BEFORE_XML_DECLARATION, then it will be set to XMLOutputterStates.BEFORE_DTD_DECLARATION, otherwise if the state is XMLOutputterStates.START_TAG_OPEN then it will be set to XMLOutputterStates.WITHIN_ELEMENT, otherwise the state will not be changed.

Parameters:
ch - the character array containing the text to be written, not null.
start - the start index in the array, must be >= 0 and it must be < ch.length.
length - the number of characters to read from the array, must be > 0.
Throws:
IllegalStateException - if getState() == ERROR_STATE.
IllegalArgumentException - if ch == null || start < 0 || start >= ch.length || length < 0.
IndexOutOfBoundsException - if start + length > ch.length.
IOException - if an I/O error occurs; this will set the state to XMLOutputterStates.ERROR_STATE.

comment

public final void comment(String text)
                   throws IllegalArgumentException,
                          IOException
Writes the specified comment. The comment should not contain the string "--".

If the state equals XMLOutputterStates.BEFORE_XML_DECLARATION, then it will be set to XMLOutputterStates.BEFORE_DTD_DECLARATION, otherwise if the state is XMLOutputterStates.START_TAG_OPEN then it will be set to XMLOutputterStates.WITHIN_ELEMENT, otherwise the state will not be changed.

Parameters:
text - the text for the comment be written, not null.
Throws:
IllegalStateException - if getState() == ERROR_STATE.
IllegalArgumentException - if text == null.
IOException - if an I/O error occurs; this will set the state to XMLOutputterStates.ERROR_STATE.

pi

public final void pi(String target,
                     String instruction)
              throws IllegalStateException,
                     IllegalArgumentException,
                     IOException
Writes a processing instruction. A target and an optional instruction should be specified.

A processing instruction can appear above and below the root element, and between elements. It cannot appear inside an element start or end tag, nor inside a comment. Processing instructions cannot be nested.

If the state equals XMLOutputterStates.BEFORE_XML_DECLARATION, then it will be set to XMLOutputterStates.BEFORE_DTD_DECLARATION, otherwise the state will not be changed.

Parameters:
target - an identification of the application at which the instruction is targeted, not null.
instruction - the instruction, can be null, which is equivalent to an empty string.
Throws:
IllegalStateException - if getState() == ERROR_STATE.
IllegalArgumentException - if target == null.
IOException - if an I/O error occurs; this will set the state to XMLOutputterStates.ERROR_STATE.

cdata

public final void cdata(String text)
                 throws IllegalStateException,
                        IllegalArgumentException,
                        IOException
Writes a CDATA section.

A CDATA section can contain any string, except "]]>". This will, however, not be checked by this method.

Left angle brackets and ampersands will be output in their literal form; they need not (and cannot) be escaped using "&lt;" and "&amp;".

If the specified string is empty (i.e. "".equals(text), then nothing will be output.

If the specified string contains characters that cannot be printed in this encoding, then the result is undefined.

Parameters:
text - the contents of the CDATA section, not null.
Throws:
IllegalStateException - if getState() != START_TAG_OPEN && getState() != WITHIN_ELEMENT
IllegalArgumentException - if text == null.
IOException - if an I/O error occurs; this will set the state to XMLOutputterStates.ERROR_STATE.

close

public final void close()
                 throws IllegalStateException,
                        IOException
Closes all open elements. After calling this method, only the whitespace(String) method can be called.

To flush the output stream, call getWriter().flush().

Throws:
IllegalStateException - if getState() != START_TAG_OPEN && getState() != WITHIN_ELEMENT && getState() != AFTER_ROOT_ELEMENT
IOException - if an I/O error occurs; this will set the state to XMLOutputterStates.ERROR_STATE.


See http://xmlenc.sourceforge.net/.