Factory Properties
As with SAX and DOM, StAX readers and writers can be configured by changing both settings defined in the specification and any implementation-specific settings that a parser vendor may create for their implementation. In StAX, these settings are referred to as properties. Properties are set using the setProperty( ) method of XMLInputFactory and XMLOutputFactory. Values of properties, which may or may not have been set by your code, can be retrieved using the getProperty( ) method. This method can be invoked both on factories and the readers and writers they have created. Once set on a factory, properties affect all readers and writers subsequently created by the various create methods.
|
Boolean Properties of XMLInputFactory
Table 8-5 contains a list of the properties of XMLInputFactory that are set using java.lang.Boolean values. Most of these have their default values specified in the StAX specification. Support for some of these properties is optional. Like DOM, there is a separate mechanism to test if a property is supported by an implementation through the isPropertySupported( ) method. If you try to set a property that is not supported, setProperty( ) will throw a java.lang.IllegalArgumentException indicating that a property is not supported.
Table 8-5. Boolean properties of XMLInputFactory
Feature name | Default | Required? |
---|---|---|
javax.xml.stream.isValidating | False | No |
javax.xml.stream.isCoalescing | False | Yes |
javax.xml.stream.isNamespaceAware | True | No |
javax.xml.stream.isReplacingEntityReferences | True | Yes |
javax.xml.stream.isSupportingExternalEntities | None | Yes |
javax.xml.stream.isValidating
-
Enable or disable XML validation.
javax.xml.stream.isCoalescing
-
Force the parser to combine adjacent CHARACTERS and CDATA events into a single CHARACTERS event.
javax.xml.stream.isNamespaceAware
-
Enable or disable namespace support.
javax.xml.stream.isReplacingEntityReferences
-
If this property is set to true, internal entity references are replaced with their character representation. If it is set to false, these entities result in ENTITY_REFERENCE events. This does not apply to the five predefined XML entities (<, &, >, ", and '), which are always replaced by their character representation.
javax.xml.stream.isSupportingExternalEntities
-
Enable or disable resolution of external parsed entities.
Object Properties of XMLInputFactory
XMLInputFactory defines three interfaces that can be implemented to alter the behavior of XMLStreamReader and XMLEventReader instances. Implementations of these interfaces are set on an XMLInputFactory either through calling setProperty( ) with one of the property names from Table 8-6 or by calling the specific setter for each interface.
Table 8-6. Interfaces for object properties of XMLInputFactory
Interface name | Property name | Setter |
---|---|---|
XMLResolver |
javax.xml.stream.resolver |
setResolver( ) |
XMLReporter |
javax.xml.stream.reporter |
setReporter( ) |
XMLEventAllocator |
javax.xml.stream.allocator |
setAllocator( ) |
XMLResolver
Implementing the javax.xml.stream.XMLResolver interface allows you to override the default resource resolution mechanism for resolving external resources while parsing a documenttypically an external DTD. The interface defines one method:
public Object resolveEntity(String publicID, String systemID, String baseURI, String namespace) throws XMLStreamException;
The result of a call to resolveEntity( ) must be a javax.xml.stream.XMLStreamReader, a java.io.InputStream, or a javax.xml.stream.XMLEventReader.
XMLReporter
The java.xml.stream.XMLReporter interface allows you to capture warnings and nonfatal errors that arise while parsing the document. Without setting this property on XMLInputFactory, there is no reporting of warnings or nonfatal errors. The interface defines one method:
public void report(String message, String errorType, Object relatedInformation, Location location) throws XMLStreamException;
XMLEventAllocator
An implementation of the javax.xml.stream.util.XMLEventAllocator interface is used inside implementations of XMLEventReader to create an XMLEvent object based on the current state of the underlying XMLStreamReader. By contract, an XMLEventAllocator should never modify the state of the XMLStreamReader. The interface defines three methods:
public XMLEventAllocator newInstance( ); public XMLEvent allocate(XMLStreamReader reader) throws XMLStreamException; public void allocate(XMLStreamReader reader, XMLEventConsumer consumer) throws XMLStreamException;
The newInstance( ) method should return a new instance of this XMLEventAllocator implementation. This allows XMLInputFactory instances to create a new allocator instance per reader. The two allocate methods should read the current state of the XMLStreamReader and create the appropriate XMLEvent objects. According to the specification, XMLEventAllocator instances are not required to use XMLEventFactory, but it is recommended. The first version of allocate should return one XMLEvent based on the state of the reader. The second passes in an instance of the XMLEventConsumer interface (which defines one methodadd( )that accepts an XMLEvent object) to which XMLEvent should be passed and, as a result, one call to allocate( ) can result in multiple method calls on the XMLEventConsumer object. However, since XMLEventReader implementations are free to call either allocate( ) method; you can't count on this multievent behavior. A significant problem with implementing this interface is that there's no way to obtain the default XMLEventAllocator implementation for a StAX implementation. This means there is no vendor-independent way to create an implementation of XMLEventAllocator that only overrides allocation of only some types of event. If you expect to use XMLEventAllocator extensively, you may be best served by standardizing on a StAX implementation so that you can extend its default implementation of XMLEventAllocator.
XMLOutputFactory
XMLOutputFactory has only one property defined in the StAX specification, javax.xml.stream.isRepairingNamespaces . This property allows you to avoid defining a prefix for each namespace URI in your document. Instead, the XMLStreamWriter or XMLEventWriter implementation will automatically assign a prefix. This can cut down on the amount of namespace handling code you need to write, but with the cost of some potentially very ugly namespace prefixes like zdef-1428660340. If your document is going to be read by humans that expect a particular (or short) namespace prefix, using this property may cause you some headaches.