blob: 77ab93835aec114d24a55c5aa74177c2eb137f1d [file] [log] [blame]
<?xml version="1.0"?>
<!--
Copyright 2002,2004 The Apache Software Foundation.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<document>
<properties>
<title>XML Pipelines</title>
<author email="jstrachan@apache.org">James Strachan</author>
</properties>
<body>
<section name="XML Pipelines">
<p>
Rather like the Cocoon project, Jelly also supports the concept of <i>XML pipelines</i>.
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 <a href="http://sax.sf.net/">SAX</a>.
</p>
<subsection name="A Jelly script is a compiled SAX stream">
<p>
Jelly compiles XML into a <a href="apidocs/org/apache/commons/jelly/Script.html">Script</a>.
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.
</p>
<p>
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.
</p>
</subsection>
<subsection name="Using Tags as source, filter, transformation or destination in a pipeline">
<p>
Each Jelly <a href="apidocs/org/apache/commons/jelly/Tag.html">Tag</a>
is given an <a href="apidocs/org/apache/commons/jelly/XMLOutput.html">XMLOutput</a>
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.
</p>
<p>
A Jelly Tag can choose how to invoke its body. So it could
</p>
<ul>
<li>
optionally evaluate its body based on some condition
</li>
<li>
loop over its body via some iteration
</li>
<li>
parse its body into some DOM model or turn the XML events into some kind of Java objects
or other kind of data structure
</li>
<li>
perform some arbitrary XML event transformation, like XSLT or apply some SAX Filter etc.
</li>
<li>
output the XML events to some destination
</li>
</ul>
<p>
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
</p>
<ul>
<li>
parsing XML, transforming it with XSLT or using XPath via the <a href="libs/xml/tags.html">xml</a> library
</li>
<li>
parsing HTML via the <a href="libs/html/tags.html">html</a> library
</li>
<li>
performing XML validation against DTD, XML Schema or RelaxNG using the <a href="libs/validate/tags.html">validate</a> library
</li>
<li>
performing SOAP operations via Apache Axis with the <a href="libs/soap/tags.html">soap</a> library
</li>
<li>
mixing and matching the processing of XML in pipelines with support for other libraries like
Ant, SQL, HTTP, JMS etc.
</li>
</ul>
<p>
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.
</p>
<source><![CDATA[
<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>
]]>
</source>
</subsection>.
</section>
</body>
</document>