| Core Interfaces |

The Xerces Native Interface core contains a series of interfaces and classes designed to communicate a document's "streaming" information set. This page documents the API available for receiving this information in the following sections:

- Document Information
- DTD Information

A few examples are also included to illustrate the use of the streaming information set:

- Pass-Through Document Handler Filter
- Upper-Case Filter

For information regarding the parser configuration framework, refer to the Parser Configuration documentation.

| The source code for the samples in this document are included in the downloaded packages for Xerces2.

| Document Information |

The document information is communicated using the `XMLDocumentHandler` interface. In addition, the `XMLDocumentFragmentHandler` interface is included to get information regarding document fragments. Programmers already familiar with the SAX programming interfaces should be immediately comfortable programming to the Xerces Native Interface. However, XNI does not depend on the SAX interfaces and classes.

| All of the interfaces and classes documented on this page are contained within the `org.apache.xerces.xni` package.

| Interface XMLDocumentHandler |

| Communicates document structure and content information. This is the most important handler interface in the Xerces Native Interface.

| Interface XMLDocumentFragmentHandler |

| Communicates information about a document fragment. This interface is provided for convenience in defining a document fragment but is not required to be used by a compliant XNI parser component or configuration.

Besides the handler interfaces there are several related interfaces and classes. All of these are described below.

| Class XNIException |

Represents a generic Xerces Native Interface exception.

Note: This exception extends `java.lang.RuntimeException`. Therefore, even though all of the handler interface methods can throw this type of exception, it is not explicitly required to be caught. Since XNI is intended to be an internal set of interfaces, it is expected that XNI implementations will provide a catch block for this exception at the top level so that XNI exceptions do not "leak" out to the application code.

| Interface Augmentations |

This interface enables arbitrary information to be passed through the pipeline on various calls from one component to another. XNI tries to model, as close as is feasible, the information made available by the W3C's InfoSet specification. The Augmentations interface is intended to permit components to augment the infoset for some document at almost any given point. Many other XNI interfaces besides the DocumentHandler support Augmentations parameters.

One kind of particularly useful Infoset augmentation is provided through the Post-Schema validation Infoset. For information about Xerces2's support of the PSVI, and how Augmentations are used in a well-defined way to permit this support, see the documentation for the PSVI Writer and PSVI Configuration samples.

| Interface XMLResourceIdentifier |

This interface serves to gather together information relevant to any kind of XML resource (external entity, notation, schema grammar, etc.). There are five fields in this interface:

- baseSystemId: The URI against which the literal systemId in the entity (or the URI to be resolved in the `schemaLocation` attribute as the case may be) should be resolved relative to.
- literalSystemId: The "real" (unexpanded) value of the systemId (or `schemaLocation`) of the entity which this object relates to.
- expandedSystemId: The value of the systemId (or `schemaLocation`) after being subjects to relative URI expansion. SAX programmers will be familiar with this concept from the SAX Locator interface, for example; this property maps to the `systemId` property of that interface.
- publicId: the publicId of the entity.
- namespace: the namespace of the entity. This is useful when the resource is some kind of namespace-aware grammar (an XML Schema, for example).

As in the case of other XNI objects, XMLResourceIdentifiers cannot be depended upon to retain their values between calls; hence, callees should extract whatever information they need from them (or clone the object) before returning control back to the parser.

| Interface XMLLocator |

This interface is used to communicate the document location to the various handler interfaces. The application can use the methods on this interface to query the public, literal system, and expanded system base system identifier as well as the line number, column number and the encoding of the entity currently being parsed.

A locator is passed as a parameter in the first method called by the `XMLDocumentHandler`, `XMLDocumentFragmentHandler`, and `XMLDTDHandler` interfaces.

Note: Parser components that emit document information are not required to provide a locator object. However, the Xerces2 reference implementation does provide a locator to registered handlers.

| Class QName |

The QName object is a structure of qualified name information.

Note: The fields of this object have public visibility but should be considered to be read-only to all methods that are passed this object. The caller that creates and passes the QName object "owns" the data. Therefore, callees should not retain a reference to the passed object and are required to copy the references contained in the object if the data is to be used beyond the scope of the method call.

| Interface XMLAttributes |

This interface represents the collection of attributes that is passed to the `startElement` and `emptyElement` methods of the `XMLDocumentHandler` and `XMLDocumentFragmentHandler` interfaces. This collection of attributes contains all of the information about the attributes of an element (except order) and is editable.

This interface is also capable of storing information about entities appearing in the attribute value. However, it should be noted that if entity information is set for an attribute, then the non-normalized value of the attribute must also be stored because the offsets and lengths of entities in the attribute have no meaning for the normalized value.

| Class XMLString |

The XMLString object is a structure for holding text information. This object allows the underlying implementation to pass text information by using its own internal character buffer without creating new String objects or copying the data.

Note: The fields of this object have public visibility but should be considered to be read-only to all methods that are passed this object. The caller that creates and passes the XMLString object "owns" the data. Therefore, callees should not retain a reference to the passed object and are required to copy the information contained in the object if the data is to be used beyond the scope of the method call. Also, callees should never modify the contents of the character array directly as that could adversely affect the operation of the caller.

| Interface NamespaceContext |

| Namespace context information for document fragments. This object is passed to the first method of the `XMLDocumentFragmentHandler` interface.

| DTD Information |

The DTD information is communicated through two interfaces: `XMLDTDHandler` and `XMLDTDContentModelHandler`. The first handler interface passes the basic DTD information whereas the second handler interface breaks down each element declaration content model into separate callbacks.

| Interface XMLDTDHandler |

| Communicates basic DTD information such as element and attribute declarations. The implementor of this interface can also be informed of characters within an ignored conditional section.

| Interface XMLDTDContentModelHandler |

| Breaks down each element declaration's content model into a set of separate methods so that handlers don't have to reparse the content model string given in the `XMLDTDHandler#elementDecl(String,String)` method. This separation also helps those applications that want to know boundaries of entities when used as part of an element's content model.

| Examples |

The following examples demonstrate the basic use of the various XNI handler interfaces.

| Pass-Through Document Handler Filter |

The following example demonstrates a basic pass-through document handler filter. This filter receives document handler events and passes them through to the next document handler.

    import org.apache.xerces.xni.QName;
    import org.apache.xerces.xni.XMLAttributes;
    import org.apache.xerces.xni.XMLDocumentHandler;
    import org.apache.xerces.xni.XMLLocator;
    import org.apache.xerces.xni.XMLString;
    import org.apache.xerces.xni.XNIException;
    import org.apache.xerces.xni.XMLResourceIdentifier;
    import org.apache.xerces.xni.Augmentations;

    public class PassThroughFilter
        implements XMLDocumentHandler {

        // Data

        protected XMLDocumentHandler fDocumentHandler;
        protected XMLDocumentSource fDocumentSource;

        // Public methods

        public void setDocumentHandler(XMLDocumentHandler handler) {
            fDocumentHandler = handler;
        }

        // XMLDocumentHandler methods

        public void startDocument(XMLLocator
        locator, String encoding, NamespaceContext namespaceContext, Augmentations augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.startDocument(locator, encoding, namespaceContext, augs);
            }
        }

        public void xmlDecl(String version, String encoding,
                            String standalone, Augmentations augs) throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.xmlDecl(version, encoding, standalone,
                    augs);
            }
        }

        public void doctypeDecl(String rootElement, String publicId,
                                String systemId, Augmentations augs) throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.doctypeDecl(rootElement, publicId,
                        systemId, augs);
            }
        }

        public void comment(XMLString text,
            Augmentations augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.comment(text, augs);
            }
        }

        public void processingInstruction(String target, XMLString data, Augmentations augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.processingInstruction(target, data, augs);
            }
        }

        public void startElement(QName
        element, XMLAttributes
            attributes, Augmentations augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.startElement(element, attributes, augs);
            }
        }

        public void emptyElement(QName
        element, XMLAttributes
            attributes, Augmentations augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.emptyElement(element, attributes, augs);
            }
        }

        public void endElement(QName element,
            augmentations augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.endElement(element, augs);
            }
        }

        public void startGeneralEntity(String name,
                XMLResourceIdentifier resId,
                String encoding, Augmentations augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.startEntity(name,
                                             resId, encoding, augs);
            }
        }

        public void textDecl(String version, String encoding, Augmentations augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.textDecl(version, encoding, augs);
            }
        }

        public void endGeneralEntity(String name, Augmentations augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.endEntity(name, augs);
            }
        }

        public void characters(XMLString text,
            Augmentations augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.characters(text, augs);
            }
        }

        public void ignorableWhitespace(XMLString text ,
            Augmentations augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.ignorableWhitespace(text, augs);
            }
        }

        public void startCDATA(Augmentations
            augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.startCDATA(augs);
            }
        }

        public void endCDATA(Augmentations augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.endCDATA(augs);
            }
        }

        public void endDocument(Augmentations
                augs)
            throws XNIException {
            if (fDocumentHandler != null) {
                fDocumentHandler.endDocument(augs);
            }
        }

        public void setDocumentSource(XMLDocumentSource source) {
            fDocumentSource = source;
        }

        public XMLDocumentSource getDocumentSource(XMLDocumentSource source) {
            return fDocumentSource;
        }

    } // class PassThroughFilter

| Upper-Case Filter |

The following code extends the pass-through document handler filter to upper-case all of the element names.

    import org.apache.xerces.xni.QName;
    import org.apache.xerces.xni.XMLAttributes;
    import org.apache.xerces.xni.XNIException;
    import org.apache.xerces.xni.Augmentations;
    public class UpperCaseFilter
        extends PassThroughFilter {

        // Data

        private final QName fQName = new QName();

        // XMLDocumentHandler methods

        public void startElement(QName element, XMLAttributes attributes,
            Augmentations augs)
            throws XNIException {
            super.startElement(toUpperCase(element), attributes, augs);
        }

        public void emptyElement(QName
        element, XMLAttributes
            attributes, Augmentations augs)
            throws XNIException {
            super.emptyElement(toUpperCase(element), attributes, augs);
        }

        public void endElement(QName element,
            Augmentations augs)
            throws XNIException {
            super.endElement(toUpperCase(element), augs);
        }

        // Protected methods

        protected QName toUpperCase(QName qname) {
            String prefix = qname.prefix != null
                          ? qname.prefix.toUpperCase() : null;
            String localpart = qname.localpart != null
                             ? qname.localpart.toUpperCase() : null;
            String rawname = qname.rawname != null
                           ? qname.rawname.toUpperCase() : null;
            String uri = qname.uri;
            fQName.setValues(prefix, localpart, rawname, uri);
            return fQName;
        }

    } // class UpperCaseFilter

Copyright © 1999-2002 The Apache Software Foundation. All Rights Reserved.