morphis logo morphis | wax   
morphis manual
manual
 

Processing
   Dispatching
   Requesting
   Translating

Installation
   Requirements
   Instructions
   Config Properties

Dispatching
   Configuration
   Pre/Post Filters

Requestors
   URL Requesting
   Servlet Chaining
   Run-time Instructs
   Custom Requestors

Translators
   Non-Translator
   Custom Translators

SAX Translators
   XSLT Translation
   Custom SAX Filters

SAX Translator: Writing Custom SAX Filters

Custom SAX Translator Filters are useful for performing complex translation based on SAX Events outside of the context of an XSLT Translation. For instance, you can write a SAX Filter to append a string to the end of every "href" attribute it finds. Or, you can build a SAX Filter that extracts all character data and converts it to another language.

Understanding how a SAX Filter works should be easy if you understand how XML SAX events, and the SAX 1 DocumentHandler interface. In fact, all SAX Filters implement this interface.

A Custom SAX Filter must extend org.morphis.translator.TranslatorFilter. A TranslatorFilter contains a handle to a delegate DocumentHandler with the name nextFilter. Therefore, SAX events (from the DocumentHandler interface) must be explicity passed to the next object in the filter list. This the TranslatorFilter's default behavior. Therefore, if you do not want an XML element or attribute to be passed to the next filter, you must "eat" the element by ensuring it does not pass through as shown in this example:

public void startElement(String name, AttributeList atts)
  throws SAXException
{
    if (!name.equals("foo") {
        ((TranslatorFilter)nextFilter).startElement(name, atts);
    }
}

public void endElement(String name)
   throws SAXException
{
    if (!name.equals("foo") {
        ((TranslatorFilter)nextFilter).endElement(name);
    }
}

You can also use the context member variable to obtain information about the context of the request, or Servlet information.

Custom SAX Filters are instantiated in an object pool, and the lifecycle of a filter is only one request. Therefore, the constructor to a custom SAX Filter must be public, and should be empty. If you need to set up state, you should implement the setState() method which is called once before processing occurs. You should also implement reset(), which is called once after processing completes.

The last filter in a chain is a special case of SAX filter. The last filter is responsible for turning SAX events into an output stream. Therefore, if your filter is the last filter in a SAXTranslator process, you must implement the setOutputStream method. This method is called before processing occurs, and provides the SAX filter with an output stream to write output. Your filter is responsible for turning the startElement, endElement, characters, and other SAX DocumentHandler events into a byte stream. Apache Xerces provides serializers in the org.apache.xml.serialize package.

morphis SourceForge Logo