wissel.net

Usability - Productivity - Business - The web - Singapore & Twins

Extracting data from Domino into PDF using XSLT and XSL:FO (Part 3)


This entry is part of the series Domino, XSL:FO and XSLT that dives into the use of XSLT and XSL:FO in IBM Lotus Domino.

In Part 2 I introduced the Java code required to output PDF from XSL:FO and how that code can be called from an XAgent. Now lets have a look at XSL:FO itself. It is a W3C defined standard to layout documents. You could consider it as competitor to PostScript or PDF. XSL:FO contains both layout instructions and content. Since it is expressed entirely in XML, it is easy to manipulate (follow me for a moment and accept XML is easy) and - more importantly easy to split content and layout for reuse. Typically a complete XSL:FO document would be only an intermediate step in PDF production. The report design (without data) would be contained in an XSLT stylesheet that gets merged with XML data. You could consider XSLT the "templating language" of XSL:FO.
A XSL:FO document has a single <fo:root> element. This contains one or more page-sequence elements, that contain the actual content and a layout-master-set, that defines the pages.
XSL:FO layout-master-set
Besides the page size (and content orientation) a simple-page-master defines header, footer, left and right column (called regions). You need to get your math right there. The margin and the regions are both substracted from the page size to compute the real margins. When you have a margin="1cm" and a region-start with 3cm width, then the left margin is 4cm. Read up the XSL:FO tutorial on w3schools.com for more details.
The main element region-body allows to specify a column-count attribute that will create multi-column page layouts without the need for a table and a manual calculation of column content. You also could define alternating page masters, like left and right pages or different pages for a chapter beginning - read details in the repeatable-page-master-alternative specification.
Your main content is contained in one or more page-sequences.
page-sequence
The page sequence contains the content. Don't get confused: a page-sequence represents content of n number of pages (n >=1), not just one page. You need more than one page sequence only when you want the page layout to use a different master/style (of course using the alternatives mechanism described above you can achieve alternate styles inside a single page sequence). The page sequence contains one or more flows. A flow is targeted at a region (there are 5 of them) and contains block elements (think HTML div,p,table etc.) that contain the content. There are a huge number of specialised attributes and elements (stuff like watermarks or graphics) available you can learn about in the specifications.
In practise you write a sample XSL:FO document and transform it into PDF. Once you are satisfied with the results, you then convert the XSL:FO document into an XSLT stylesheet. This is easier than it sounds, you simply wrap xsl:template tags around your fo and replace your sample content with xsl:apply-templates statements. w3schools has a simple example. Of course XSLT is a interesting topic on its own, go and read the XSLT 2.0 and XPath 2.0 Programmer's Reference (also available on Kindle ).
Next stop: How to pull Notes data into XML for processing.

Posted by on 28 April 2012 | Comments (2) | categories: Show-N-Tell Thursday XPages

Comments

  1. posted by Stephan H. Wissel on Thursday 19 December 2013 AD:
    The OpenNTF data moving animal - no coding required. Does your xslt work on the command line? Pro tip: to make the string readable use |content including " format|
  2. posted by Robert Lozano on Thursday 19 December 2013 AD:
    Hello Stephan,

    I need to transform dxl into simple xml. I found an example in the Lotus Domino 8.5 Designer Help

    in it there is

    private String promote_xsl =
    "<?xml version='1.0'?>"+
    "<xsl:stylesheet xmlns:xsl='{ Link }
    "version='1.0'>"+
    "<xsl:template match='document'>"+
    " <xsl:element name='{translate(@form,\" \", \"\")}'>"+
    " <xsl:for-each select='item'>"+
    " <xsl:choose>"+
    " <!-- Items whose names have dollars are skipped -->"+
    " <xsl:when test='contains(@name, \"$\")'/>"+
    " <!-- Items named SaveOptions are skipped -->"+
    " <xsl:when test='@name=\"SaveOptions\"'/>"+
    " <!-- Items starting with 'dsp' are skipped -->"+
    " <xsl:when test='starts-with(@name, \"dsp\")'/>"+
    " <xsl:otherwise>"+
    " <xsl:element name='{@name}'>"+
    " <xsl:value-of select='*'/>"+
    " </xsl:element>"+
    " </xsl:otherwise>"+
    " </xsl:choose>"+
    " </xsl:for-each>"+
    " </xsl:element>"+
    "</xsl:template>"+
    "</xsl:stylesheet>\n";


    The thing is that in runtime, I get this error

    [Fatal Error] :1:86: Element type "xsl:stylesheet" must be followed by either attribute specifications, ">" or "/>".
    NotesException: Not implemented
    at lotus.domino.Processor.process(Unknown Source)
    at lotus.domino.local.Document.generateXML(Unknown Source)
    at JavaAgent.NotesMain(JavaAgent.java:27)
    at lotus.domino.AgentBase.runNotes(Unknown Source)
    at lotus.domino.NotesThread.run(Unknown Source)
    Caused by: javax.xml.transform.TransformerConfigurationException: [ERR 0641] An error occurred while parsing document: 'Element type "xsl:stylesheet" must be followed by either attribute specifications, ">" or "/>".'.
    at com.ibm.xtq.xslt.jaxp.ConfigurationErrorHandler.report(Unknown Source)
    at com.ibm.xtq.utils.Reporter.report(Unknown Source)
    at com.ibm.xtq.ast.parsers.xslt.XSLTParser.reportError(Unknown Source)
    at com.ibm.xtq.ast.parsers.xslt.XSLTParser.parse(Unknown Source)
    at com.ibm.xtq.xslt.drivers.XSLTCompiler.makeAST(Unknown Source)
    at com.ibm.xtq.xslt.drivers.XSLTCompiler.buildAST(Unknown Source)
    at com.ibm.xtq.xslt.drivers.XSLTCompiler.compile(Unknown Source)
    at com.ibm.xtq.xslt.jaxp.compiler.TransformerFactoryImpl.createTemplates(Unknown Source)
    at com.ibm.xtq.xslt.jaxp.AbstractTransformerFactory.newTransformer(Unknown Source)

    and cannot seem to find what is going on. I am trying to export documents in an nsf out to a simple xml file in order to import it into Excel. Do you know a better tool for the job at hand?