FO Rendering

(1Q22)


eXist-db can perform FO (Formatting Objects) rendering inside XQuery code. The FO can be generated used XSL (i.e. XSL:FO) if desired. For this you need to use the xslfo module.

The xslfo module

eXist-db XSL:FO module allows you to do FO rendering from XQuery code using an appropriate FO Renderer; eXist-db supports Apache FOP and RenderX XEP. Previously there was also support for AntennaHouse, but that was removed as it was unmaintained, we would welcome a new contribution to support AntennaHouse again.

Selection of the renderer is configured in eXist-db's conf.xml file. By default eXist-db ships with and is configured to use Apache FOP, see: Using the Apache FOP Renderer

If you wish to use RenderX XEP instead, see Using the RenderX XEP FO Renderer.

Its function namespace is http://exist-db.org/xquery/xslfo.

xslfo:render()

The xslfo:render function renders an FO document and returns you the result. It has two signatures:

xslfo:render($document as node(), $media-type as xs:string, $parameters as node()?) as xs:base64Binary
xslfo:render($document as node(), $media-type as xs:string, $parameters as node()?, $processor-config as node()?) as xs:base64Binary
$document

The FO document to be rendered.

$media-type

The Internet Media Type of the desired result. This provides a hint to the renderer as to what format it should render

$parameters

Specify any optional parameters for the rendering of the FO document, these are processor specific.

$processor-config

An optional configuration document for the processor, this is processor specific.

Streaming the result to a Web Browser

If you wish to Stream the result of xslfo:render directly to the Web Browser (i.e. HTTP Response), you can send the output of xslfo:render directly to the function response:stream-binary. This can be useful for example when you want an XQuery to download a PDF directly to the Web Browser.

Using the Apache FOP Renderer

By default eXist-db ships with and is configured to use Apache FOP. It is configured in eXist-db's conf.xml file through the following configuration option:

<module uri="http://exist-db.org/xquery/xslfo" class="org.exist.xquery.modules.xslfo.XSLFOModule">
  <parameter name="processorAdapter" value="org.exist.xquery.modules.xslfo.ApacheFopProcessorAdapter"/>
</module>

An example of using Apache FOP to transform FO and save the result to a PDF file in the database.

xquery version "1.0";

declare namespace file = "http://exist-db.org/xquery/file";
declare namespace xmldb = "http://exist-db.org/xquery/xmldb";
declare namespace xslfo = "http://exist-db.org/xquery/xslfo";

let $fo := fn:doc('/db/test-fo.xml')
let $pdf := xslfo:render($fo, "application/pdf", (), ())
return
  xmldb:store("/db", "result.pdf", $pdf, "application/pdf")
Using Apache FOP from XQuery

Using the RenderX XEP FO Renderer

To configure eXist-db to use RenderX XEP instead of Apache FOP, follow these steps:

  1. From a RenderX distribution, copy the files lib/xep.jar and lib/xt.jar into the folder $EXIST_HOME/lib.

  2. eXist-db uses a number of configuration files, one per script, to determine which jar files to load. You should edit the XML files in the folder $EXIST_HOME/etc to add the following configuration (adjust the version numbers appropriately):

    <dependency>
      <groupId>com.renderx.xep</groupId>
      <artifactId>xep</artifactId>
      <version>4.30.961</version>
      <relativePath>xep.jar</relativePath>
    </dependency>
    <dependency>
      <groupId>com.renderx.xep.thirdparty.com.jclark.xsl</groupId>
      <artifactId>xt</artifactId>
      <version>4.30.961</version>
      <relativePath>xt.jar</relativePath>
    </dependency>
    
  3. Create the folder $EXIST_HOME/renderx

  4. From a RenderX distribution, copy the files xep.xml and rolemap.xml, and the folders fonts, hyphen, and images into the folder $EXIST_HOME/renderx.

  5. Edit the file $EXIST_HOME/renderx/xep.xml to make the following changes:

    • From:

      <option name="LICENSE" value="license.xml"/>

      To:

      <option name="LICENSE" value="renderx/license.xml"/>
    • From:

      <option name="BROKENIMAGE" value="images/404.gif"/>
      <option name="LOGO" value="images/logo-renderx.svg"/>
      <option name="STAMP_PNG" value="images/stamp-renderx.png"/>
      <option name="ROLE_MAP" value="rolemap.xml"/>

      To:

      <option name="BROKENIMAGE" value="renderx/images/404.gif"/>
      <option name="LOGO" value="renderx/images/logo-renderx.svg"/>
      <option name="STAMP_PNG" value="renderx/images/stamp-renderx.png"/>
      <option name="ROLE_MAP" value="renderx/rolemap.xml"/>
    • From:

      <fonts xml:base="fonts/" default-family="Helvetica"/>

      To:

      <fonts xml:base="renderx/fonts/" default-family="Helvetica"/>
    • From:

      <languages default-language="en-US" xml:base="hyphen"/>

      To:

      <languages default-language="en-US" xml:base="renderx/hyphen"/>
  6. Copy your RenderX XEP license file (license.xml) that you have been provided by RenderX into $EXIST_HOME/renderx.

  7. Edit the file $EXIST_HOME/conf.xml to make the following changes:

    From:

    <module uri="http://exist-db.org/xquery/xslfo" class="org.exist.xquery.modules.xslfo.XSLFOModule">
      <parameter name="processorAdapter" value="org.exist.xquery.modules.xslfo.ApacheFopProcessorAdapter"/>
    </module>

    To:

    <module uri="http://exist-db.org/xquery/xslfo" class="org.exist.xquery.modules.xslfo.XSLFOModule">
      <parameter name="processorAdapter" value="org.exist.xquery.modules.xslfo.RenderXXepProcessorAdapter"/>
    </module>
  8. If eXist-db was running whilst you were making these changes, then you will need to restart it for the change to take effect.

An example of using RenderX XEP to transform FO and save the result to a PDF file on the filesystem.

xquery version "3.0";

declare namespace file = "http://exist-db.org/xquery/file";
declare namespace system = "http://exist-db.org/xquery/system";
declare namespace xslfo = "http://exist-db.org/xquery/xslfo";

let $config := fn:parse-xml(file:read(system:get-exist-home() || "/renderx/xep.xml"))
return

  let $fo := fn:doc('/db/test-fo.xml')
  let $pdf := xslfo:render($fo, "application/pdf", (), $config)
  return
  file:serialize-binary($pdf, "/tmp/fop.pdf")
Using RenderX XEP from XQuery