Use Inkscape and XSLT to Create Cross-Platform Reports and Forms

Listing 5. A Portion of the PHP Script That Transforms the Claim
XML into an SVG and Displays It in a Browser

// import the SVG XSLT
$xsl = new XSLTProcessor();
$xsl->importStyleSheet(DOMDocument::load("svg_xslt.xsl"));
// load the claim data XML
// $claim is the database result from Listing 4
$doc = new DOMDocument();
$doc->loadXML($claim);
// tell the browser this is an SVG document
header("Content-Type: image/svg+xml");
// print the SVG to the browser
echo $xsl->transformToXML($doc);

Listing 5 is a simplified version of our solution. In our solution, there
is the possibility of having multiple pages for a single claim. To fix
this, we had to do multiple transformations, one for each page. To get the
multiple-page claims to display in the same browser window, we had to embed
them. This can be done using the embed and object HTML tags. Note
that there are several issues with browser compatibility when using these
tags. To solve the compatibility issues, we wrote a script that checks the
user's browser and decides which tag to use. Then, we set the target object
data/embedded source to a script similar to the one in Listing 5. This
allowed the Web browser to display multiple SVG images in the same window.

Other considerations must be made when using SVG images
in a Web browser environment. Internet Explorer does not have native
support for SVG images. The user is forced to use a third-party plugin to
display the images. Adobe provides one of these for free. Mozilla Firefox
has built-in support for SVG images starting with version 1.5. However,
Firefox does not support several aspects of SVG images,
such as scaling and grouped objects. Fortunately for us, all of our
users use an up-to-date version of Firefox.

That is all there is to it. Figure 5 shows a claim image with all of
the data filled in.

Figure 5. Claim Form with Sample Data

Printing and Archiving the SVG Images

Once we finished the Web end of our solution, we turned our sights toward
the rest of our integration. This meant we had to print the SVG
images and find a way to archive them. Some clients request that we send
them copies of the claims printed and/or electronically. Because all of
our back-end software is written in Python, it also meant we had to
do the XML transformation in a different language. To do all of the XML
work, we used the 4Suite XML API.

To print the images, we again turned to Inkscape, because our PostScript
printer drivers would not print the SVG images. Inkscape has a handful
of command-line options that tell Inkscape to run in command-line mode,
thus suppressing the graphical interface. The one we used to print is the
-p option. This, combined with the lpr command, allowed us to print our
images without any user interaction. Listing 6 shows how we did the same
transform we did in Listing 5, except now in Python. The example
also shows how we called Inkscape to print our claim images.

Earlier, I mentioned we often have multiple pages per claim. When
printing, this was not an issue; we simply would send each page to the
printer as a separate job. When it came to archiving, we had to do
something different. As with the Web interface, we had to group the pages,
this time into a file, not a Web browser. When archiving, we had to store the
files in PDF format, because that is what our clients wanted. To get the
images into a PDF and combine the multiple page claims, we used Inkscape
and Ghostscript.

As with printing, Inkscape has an option to export a file into PostScript
format. Instead of using -p, we use -P and pass Inkscape the desired
output filename. After all of the pages of a claim have been written
to files, we use the following Ghostscript command to put the pages into
a single PDF and archive them:

I will be glad to post the full SVG. The database stuff is a bit more complicated; it is tied into our main processing system. Basically outside of the database, without the structure and the data, it is useless.

I am going to try to get the guy who wrote it to publish an article about what he did.

I am interested in figuring out how to fill out a list of items that is variable for each record. Creating a new variable for every blank like in the template will not be a good idea, so how did you accomplished that?