Wednesday, July 25, 2012

XSLT : Fun with xslt and xpath with fop

So I wanted a generic, all things to all men style sheet transformation on my service call to generate a PDF report for any xml message.

I had to do this using XSLT 1.0 booo hiss. This really make things harder. So here is what I learned:

So the first thing I needed was a JAXB transform from incoming object to xml.

        JAXBContext context = JAXBContext.newInstance(xmlObject.getClass());
        Marshaller marshaller = context.createMarshaller();
        StringWriter sw = new StringWriter();
        marshaller.marshal(xmlObject, sw);
        return sw.toString();

The next thing was passing parameters (a report title)

            Transformer transformer = tFactory.newTransformer(xsltSrc);
            transformer.setParameter("ReportTitle", "Report Title");

<xsl:param name="ReportTitle" select="'None'"/>
<xsl:value-of select="$ReportTitle"/>

Making the element tag names human readable

  <xsl:template name="ConvertToReadable">
    <xsl:param name="text"/>
    <xsl:variable name="vUpper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
    <xsl:if test="$text != ''">
      <xsl:variable name="letter" select="substring($text, 1, 1)"/>
        <xsl:when test="contains($vUpper, $letter)">
          <xsl:value-of select="concat(' ', $letter)"/>
          <xsl:value-of select="$letter"/>
      <xsl:call-template name="ConvertToReadable">
        <xsl:with-param name="text" select="substring-after($text, $letter)"/>

Formatting and checking dates : this was a little tricky I had to use EXSLT (which is included if you use xalan) add the following namespace : xmlns:datetime="" and

 <xsl:when test="datetime:date(.) != ''">
   <xsl:value-of select="datetime:format-date(., 'yyyy/MM/dd HH:mm')"/>

Formatting and checking numbers:

<xsl:when test="number(.) = .">
  <xsl:value-of select="format-number(., '#######.#####')"/>