Using the PresentationServer XUpdate Engine in Java
1. Scope
PresentationServer applications use the XUpdate
processor to perform XUpdate transformations. The PresentationServer XUpdate
engine implements the JAXP API that can be used directly by Java programs for
experimentation purposes. This section describes the JAXP interface exposed by the
PresentationServer XUpdate engine. We assume here that you are familiar with the basics
of the JAXP APIs.
2. API
Note: The JAXP methods described in this section are the only ones supported by
PresentationServer.
2.1 Creating a Templates
- Create an instance of
org.orbeon.oxf.transformer.xupdate.TransformerFactoryImpl.
This class extends
javax.xml.transform.sax.SAXTransformerFactory.
- Call newTemplatesHandler() on the
factory. This returns an instance of
javax.xml.transform.sax.TemplatesHandler.
- A TemplatesHandler implements that SAX
ContentHandler interface. Feed this content
handler with the XUpdate program.
- Call the getTemplates() method on the
templates handler. This returns an instance of
javax.xml.transform.Templates. This object
contains the internal representation of the XUpdate
program.
2.2 Performing a Transformation
- Call newTransformer() on the
Templates object. This returns a
javax.xml.transform.Transformer
- Call transform() on the transformer by
passing a SAXSource and SAXResult
as arguments.
3. Running Your Program
To run your program, you need to have the following JAR files in
your classpath:
- PresentationServer: orbeon.jar
- dom4j: dom4j-1_4.jar
- Jaxen: jaxen-1_1-beta-1-dev.jar
- SAXPath: saxpath-dev_orbeon.jar
- Xerces: xercesImpl-2_2_1_orbeon.jar
- XML APIs: xml-apis-2_5_1.jar
To get those JAR files:
- Download
PresentationServer
- Extract orbeon.war from the ZIP archive.
- Extract the JAR files from the WAR archive. They are
stored in the WEB-INF/lib directory.
4. Sample Driver
4.1 Source Code
package org.orbeon.oxf.transformer.xupdate;
import org.apache.crimson.parser.XMLReaderImpl;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXContentHandler;
import org.dom4j.io.XMLWriter;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerException;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TemplatesHandler;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class XUpdateDriver {
private final static String XUPDATE_FACTORY =
"org.orbeon.oxf.transformer.xupdate.TransformerFactoryImpl";
public static void main(String[] args) throws TransformerException, IOException {
// Check arguments
if (args.length != 2) {
System.err.println("Syntax: java " +
XUpdateDriver.class.getName() + " input.xml xupdate.xml");
return;
}
// Perform transformation
Templates templates = createTemplates(new FileReader(args[1]));
SAXContentHandler saxContentHandler = new SAXContentHandler();
templates.newTransformer().transform(new SAXSource(new XMLReaderImpl(),
new InputSource(new FileReader(args[0]))),
new SAXResult(saxContentHandler));
// Output result
OutputFormat format = OutputFormat.createPrettyPrint();
format.setIndentSize(4);
XMLWriter xmlWriter = new XMLWriter(System.out, format);
xmlWriter.write(saxContentHandler.getDocument());
}
private static Templates createTemplates(Reader xupdateReader) {
try {
SAXTransformerFactory factory = (SAXTransformerFactory)
Class.forName(XUPDATE_FACTORY).newInstance();
TemplatesHandler templatesHandler = factory.newTemplatesHandler();
XMLReader xmlReader = new XMLReaderImpl();
xmlReader.setContentHandler(templatesHandler);
xmlReader.parse(new InputSource(xupdateReader));
return templatesHandler.getTemplates();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
4.2 Running the Driver
You can run the driver with java
org.orbeon.oxf.transformer.xupdate.XUpdateDriver input.xml
xupdate.xml. Make sure to have in your CLASSPATH the JAR
files listed earlier. Assuming that input.xml
contains:
<company> <year id="2000"> <quarter id="1" sales="80"/>
<quarter id="2" sales="56"/>
<quarter id="3" sales="97"/>
<quarter id="4" sales="150"/>
</year> <year id="2001"> <quarter id="1" sales="20"/>
<quarter id="2" sales="54"/>
<quarter id="3" sales="80"/>
<quarter id="4" sales="90"/>
</year> <year id="2002"> <quarter id="1" sales="54"/>
<quarter id="2" sales="65"/>
<quarter id="3" sales="96"/>
<quarter id="4" sales="164"/>
</year> </company>
And xupdate.xml contains:
<xu:modifications xmlns:xu="
http://www.xmldb.org/xupdate"
> <xu:function name="double"> <xu:param name="f"/>
<xu:function name="result"> <xu:param name="x"/>
<xu:value-of select="f($x) * 2"/>
</xu:function> <xu:copy-of select="$result"/>
</xu:function> <xu:function name="increment"> <xu:param name="x"/>
<xu:value-of select="$x + 1"/>
</xu:function> <xu:variable name="incrementAndDouble" select="double($increment)"/>
<xu:update select="/"> <result> <xu:value-of select="incrementAndDouble(2)"/>
</result> </xu:update> </xu:modifications>
Then the output on the console will be: