In most cases, request servicing is easily accomplished with simple commands in command arrays. However, within command arrays you have a great deal of XML processing power available through the use of shell scripts, ant scripts, Makefiles, or even XML pipelines defined with XProc (http://www.w3.org/TR/xproc/) and executed via an application like Calabash (http://norman.walsh.name/2008/projects/calabash).
The following sections show simple examples you can use as starting points to implement sophisticated XML processing as part of request servicing. Keep in mind the following:
Just as with all command arrays, the second member of the array must contain the exact path and filename used as the format's default XSL.
In many cases, keywords Mr. XML Publisher expects must be used in both the scripts and the commands that call the scripts. You must appropriately coordinate parameter values passed to your scripts, values used internally in those scripts, and filenames used for output. See Command Keywords for information on keywords.
Execution is performed from within unique temporary working directories created specifically to service each request. For security reasons, it is impossible to know in advance the full path to a request's temporary working directory; thus, you cannot use that path explicitly.
Just as with every command in a command array, all scripts, Makefiles, etc. run with the owner of the process being the owner of the web container process.
The following program listing shows a bash shell script used in Linux/Unix to format DocBook XML as PDF.
#!/bin/sh ### ### $1 is the full path to the fo/docbook.xsl styleshets ### $2 is the keyword "xmlFile.xml" ### $3 is the keyword "foFile.fo" ### $4 is the keyword "pdfFile.pdf" ### FULLSTYLESHEETPATH=$1 FOFILE=$3 PDFFILE=$4 XSLTPROC=/usr/bin/xsltproc OPTIONS="--xinclude --nonet" STRINGPARAMS="--stringparam fop1.extensions 1 --stringparam ¬ draft.watermark.image ¬ file:///usr/share/xml/docbook/xsl-stylesheets/images/draft.png" JAVA=/usr/local/java/bin/java JAVAOPTS="-Xmx384m -Xss512k" CLASSPATH=/usr/local/fop-0.95/build/fop.jar: ¬ /usr/local/fop-0.95/lib/avalon-framework-4.2.0.jar: ¬ /usr/local/fop-0.95/lib/batik-all-1.7.jar: ¬ /usr/local/fop-0.95/lib/commons-io-1.3.1.jar: ¬ /usr/local/fop-0.95/lib/commons-logging-1.0.4.jar: ¬ /usr/local/fop-0.95/lib/fop-hyph.jar: ¬ /usr/local/fop-0.95/lib/jai_core.jar: ¬ /usr/local/fop-0.95/lib/jai_codec.jar: ¬ /usr/local/fop-0.95/lib/serializer-2.7.0.jar: ¬ /usr/local/fop-0.95/lib/xalan-2.7.0.jar: ¬ /usr/local/fop-0.95/lib/xercesImpl-2.7.1.jar: ¬ /usr/local/fop-0.95/lib/xml-apis-1.3.04.jar: ¬ /usr/local/fop-0.95/lib/xml-apis-ext-1.3.04.jar: ¬ /usr/local/fop-0.95/lib/xmlgraphics-commons-1.3.1.jar FOPOPTS="-v -c /usr/local/fop-0.95/conf/fop.xconf.xml" echo "Running " $XSLTPROC $OPTIONS "-o" $FOFILE $STRINGPARAMS ¬ $FULLSTYLESHEETPATH $2 $XSLTPROC $OPTIONS -o $FOFILE $STRINGPARAMS $FULLSTYLESHEETPATH $2 echo "Running " $JAVA $JAVAOPTS "-cp" $CLASSPATH ¬ "org.apache.fop.cli.Main" $FOPOPTS "-fo" $FOFILE "-pdf" $PDFFILE $JAVA $JAVAOPTS -cp $CLASSPATH org.apache.fop.cli.Main $FOPOPTS ¬ -fo $FOFILE -pdf $PDFFILE
The bash shell script shown above would be called from the command array shown in Example 20.
The following program listing shows a build.xml file used by ant in Linux/Unix to format DocBook XML as PDF.
<?xml version="1.0"?>
<project name="XMLP_ANT_SCRIPT_PDF" default="fo" basedir=".">
<property name="fop.home" value="/usr/local/fop-0.95"/>
<taskdef name="fop" classname="org.apache.fop.tools.anttasks.Fop">
<classpath>
<fileset dir="${fop.home}/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${fop.home}/build">
<include name="fop.jar"/>
<include name="fop-hyph.jar" />
</fileset>
</classpath>
</taskdef>
<target name="fo"
description="Formats a DocBook XML project into PDF.">
<exec executable="xsltproc">
<arg line="--nonet --xinclude"/>
<arg line="-o foFile.fo"/>
<arg line="--stringparam fop1.extensions 1 ¬
--stringparam draft.watermark.image ¬
file:///usr/share/xml/docbook/xsl-stylesheets/ ¬
images/draft.png"/>
<arg line="${STYLESHEET}"/>
<arg line="${XMLFILE}"/>
</exec>
</target>
<target name="pdf"
depends="fo" description="Generates a single PDF file">
<fop format="application/pdf"
userconfig="/usr/local/fop-0.95/conf/fop.xconf.xml"
messagelevel="verbose"
fofile="foFile.fo"
outfile="${PDFFILE}" />
</target>
</project>
The build.xml file shown above would be passed to the call to ant in the command array shown in Example 21.
The following program listing shows a Makefile used in Linux/Unix to format DocBook XML as PDF:
XSLTPROC = /usr/bin/xsltproc
XSLTPROCOPTIONS = --nonet --xinclude
XSLTPROCSTRINGPARAMS = --stringparam fop1.extensions 1 ¬
--stringparam draft.watermark.image ¬
file:///usr/share/xml/docbook/xsl-stylesheets/images/draft.png ¬
JAVA = /usr/local/java/bin/java
JAVAOPTS = -Xmx384m -Xss512k
CLASSPATH=/usr/local/fop-0.95/build/fop.jar: ¬
/usr/local/fop-0.95/lib/avalon-framework-4.2.0.jar: ¬
/usr/local/fop-0.95/lib/batik-all-1.7.jar: ¬
/usr/local/fop-0.95/lib/commons-io-1.3.1.jar: ¬
/usr/local/fop-0.95/lib/commons-logging-1.0.4.jar: ¬
/usr/local/fop-0.95/lib/fop-hyph.jar: ¬
/usr/local/fop-0.95/lib/jai_core.jar: ¬
/usr/local/fop-0.95/lib/jai_codec.jar: ¬
/usr/local/fop-0.95/lib/serializer-2.7.0.jar: ¬
/usr/local/fop-0.95/lib/xalan-2.7.0.jar: ¬
/usr/local/fop-0.95/lib/xercesImpl-2.7.1.jar: ¬
/usr/local/fop-0.95/lib/xml-apis-1.3.04.jar: ¬
/usr/local/fop-0.95/lib/xml-apis-ext-1.3.04.jar: ¬
/usr/local/fop-0.95/lib/xmlgraphics-commons-1.3.1.jar
FOPOPTS= -v -c /usr/local/fop-0.95/conf/fop.xconf.xml
pdf:
$(XSLTPROC) $(XSLTPROCOPTIONS) -o foFile.fo ¬
$(XSLTPROCSTRINGPARAMS) $(STYLESHEET) $(XMLFILE)
$(JAVA) $(JAVAOPTS) -cp $(CLASSPATH) org.apache.fop.cli.Main ¬
$(FOPOPTS) -fo foFile.fo -pdf $(PDFFILE)
The Makefile shown above would be executed by the command array shown in Example 22.
The following program listings show an XProc XML pipeline and a bash shell script used to execute the pipeline in Linux/Unix. The script calls Calabash and passes in the necessary parameters. Calabash produces the FO file (foFile.fo) that the last command in the command array subsequently formats as PDF using FOP.
<p:declare-step name="main"
xmlns:p="http://www.w3.org/ns/xproc">
<p:input port="source"/>
<p:output port="result"/>
<p:input port="parameters" kind="parameter"/>
<p:option name="stylesheet" required="true"/>
<p:load name="userstyle">
<p:with-option name="href" select="$stylesheet"/>
</p:load>
<p:xslt>
<p:input port="source">
<p:pipe step="main" port="source"/>
</p:input>
<p:input port="stylesheet">
<p:pipe step="userstyle" port="result"/>
</p:input>
</p:xslt>
</p:declare-step>
#!/bin/bash
#
if [ $# -lt 1 ]
then
echo usage "$0 params"
echo Where params are the calabash parameters
exit 2
fi
/usr/local/java/bin/java -cp ¬
/usr/local/xml-commons-resolver-1.1/resolver.jar: ¬
/usr/local/xml-commons-resolver-1.1: ¬
/usr/local/calabash-0.9.3/lib/calabash.jar: ¬
/usr/local/Saxon91/saxon9.jar: ¬
/usr/local/Saxon91/saxon9-s9api.jar: ¬
/usr/local/fop-0.95/build/fop.jar: ¬
/usr/local/fop-0.95/lib/avalon-framework-4.2.0.jar: ¬
/usr/local/fop-0.95/lib/batik-all-1.7.jar: ¬
/usr/local/fop-0.95/lib/commons-io-1.3.1.jar: ¬
/usr/local/fop-0.95/lib/commons-logging-1.0.4.jar: ¬
/usr/local/fop-0.95/lib/fop-hyph.jar: ¬
/usr/local/fop-0.95/lib/jai_core.jar: ¬
/usr/local/fop-0.95/lib/jai_codec.jar: ¬
/usr/local/fop-0.95/lib/serializer-2.7.0.jar: ¬
/usr/local/fop-0.95/lib/xalan-2.7.0.jar: ¬
/usr/local/fop-0.95/lib/xercesImpl-2.7.1.jar: ¬
/usr/local/fop-0.95/lib/xml-apis-1.3.04.jar: ¬
/usr/local/fop-0.95/lib/xml-apis-ext-1.3.04.jar: ¬
/usr/local/fop-0.95/lib/xmlgraphics-commons-1.3.1.jar: ¬
/usr/local/RenderX/XEP/lib/xep.jar ¬
com.xmlcalabash.drivers.Main -d ¬
-E org.apache.xml.resolver.tools.CatalogResolver ¬
-U org.apache.xml.resolver.tools.CatalogResolver $*
The shell script shown above would be called from the command array shown in Example 23. Note that the parameters passed to the script are subsequently passed to Calabash. As of version 0.93, Calabash cannot yet use FOP in the <p:xsl-formatter> step.[10] Thus, the command array calls FOP itself to produce the PDF file.
[10] Calabash currently uses RenderX XEP in the <p:xsl-formatter> step. Check your XEP licensing terms before using XEP with Mr. XML Publisher.