XML Pipelines

Rather like the Cocoon project, Jelly also supports the concept of XML pipelines. The idea in an XML pipeline is for XML events to be created by some generator and then flow through multiple filters, transformers or processors to some ultimate output. Currently XML events are implemented via SAX.

A Jelly script is a compiled SAX stream

Jelly compiles XML into a Script. This mechanism works just the same whether the document is totally static, partially dynamic, with just a few dynamic expressions inside it, or its totally dynamic using XML pipelines or invoking SOAP services etc.

Jelly effectively turns XML into an executable Script that when its run will output XML events. So this is effectively a dynamic XML event cache. The Script can contain dynamic fragments. This means that at runtime, there is no need to parse the script as the compiled Script can be cached which avoids unnecessary XML parsers while still keeping content dynamic.

Using Tags as source, filter, transformation or destination in a pipeline

Each Jelly Tag is given an XMLOutput instance when it is invoked via the doTag() method. The XMLOutput instance is a simple lightweigtht wrapper around SAX ContentHandler and LexicalHandler instances allowing a Tag to take part in any kind of SAX based processing of XML events.

A Jelly Tag can choose how to invoke its body. So it could

  • optionally evaluate its body based on some condition
  • loop over its body via some iteration
  • parse its body into some DOM model or turn the XML events into some kind of Java objects or other kind of data structure
  • perform some arbitrary XML event transformation, like XSLT or apply some SAX Filter etc.
  • output the XML events to some destination

This means that by nesting Jelly tags together its possible to create simple or complex XML pipelines which can be easily integrated with expression languages (like Jexl and XPath) or scripting languages (like JavaScript, Jython etc) as well as using other technologies such as

  • parsing XML, transforming it with XSLT or using XPath via the xml library
  • parsing HTML via the html library
  • performing XML validation against DTD, XML Schema or RelaxNG using the validate library
  • performing SOAP operations via Apache Axis with the soap library
  • mixing and matching the processing of XML in pipelines with support for other libraries like Ant, SQL, HTTP, JMS etc.

It should be noted that highly complex, yet easy to use XML pipelines can be created since the pipelines don't have to be linear. At any point in the chain, custom logic can decide what to do next.

  <j:if test="${myBean.fooEnabled('uk')}>
    <j:file name="${userdir}/results.html">
      <x:transform xslt="asHTML.xsl">
        <soap:invoke endpoint="http://com.myserver/...">
          <x:transform xslt="foo.xsl">
            <x:parse xml="${myBean.getSomeURL()}"/>
          <x:transform>
        </soap:invoke>
      </x:transform>
    </j:file>
  </j:if>