From Wikibooks, open books for an open world
Jump to navigation Jump to search


You want to convert XML into PDF and embed SVG graphics in the output.


eXist since version 2 supports placing svg in fop rendered pdf out of the box, the only step being to activate the XSLFO module before building the source:

echo "include.module.xslfo = true" > $EXIST_HOME/extensions/local.build.properties

Beware: On headless *nix systems, make sure that there is no DISPLAY environment variable set, when eXist-db is started, otherwise the apache batik svg renderer may throw an exception.

Sample XQuery[edit]

Highlights of the xquery: The FO is created from an xsl transform: I know, this could be done with xquery, but I can reuse the xsl in other places. The document is found through a search. The xsl stylesheet resides in "views", as the pdf.xq does. I create lots of variables, but its better that way. Filename deduced from request. There may be errors, as I stripped down working code! It may be overly complicated due to my ignorance of xquery features. I think you will find your way. Application directory laid out as advised in the XRX wiki.

let $host := "http://localhost:8080/exist/rest/"
let $home := "/db/apps/myApp"
let $match := collection(concat($home, "/data"))//item[@uuid=$uuid]
let $coll := util:collection-name($match)
let $file := util:document-name($match)
let $xsls := concat($home, "/views/foPDF.xsl")
let $rand := concat("?", util:random())

let $params :=
   <param name="svgfile" value="{$host}{$home}{$file}.svg"/>
   <param name="rand" value="{$rand}"/>

let $tmp := transform:transform(doc(concat($coll, "/", $file)), doc($xsls), $params)
let $pdf := xslfo:render($tmp, "application/pdf", (), ())

(: substring-afer-last is in functx :)
let $fname := substring-after(request:get-path-info(), "/")
return response:stream-binary($pdf, "application/pdf", $fname)

Another, possibly higher performance, way to source the svgfile by the xmldb:exist qualifier:

let $host := "xmldb:exist://"

Highlights of the XSL:[edit]

<!-- passed in parameter, a fully qualified URI to the SVG file, eg:
    or in exist-db "xmldb:exist///db/apps/myApp/data/Some.svg"
<xsl:param name="svgfile" select="''"/>

<!-- passed in parameter, value eg: "?123", changes with every call
    used to force fop to reread the svg file each time
    starts with ? to be discarded in the end...
    can be left blank to have fop cache the svgfile
<xsl:param name="rand" select="''"/>

<!-- place SVG in PDF output -->
               <fo:external-graphic src="{$svgfile}{$rand}"/>