Skip to main content

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);
        IOUtils.closeQuietly(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:choose>
        <xsl:when test="contains($vUpper, $letter)">
          <xsl:value-of select="concat(' ', $letter)"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$letter"/>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:call-template name="ConvertToReadable">
        <xsl:with-param name="text" select="substring-after($text, $letter)"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>




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="http://exslt.org/dates-and-times" and


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


Formatting and checking numbers:

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


Comments

Popular posts from this blog

ADF sort of generic screen for tables with the same structure

We have a couple (about a hundred) of tables with the same structure (Code, Description, Create Date, Update Date). So I wanted to do something simple so that I did not have to create all these screens 1) EO   I created the EO based on one of the tables I had that had the above columns. I then Added a transient attribute called table name to my EO based on a groovy expression. (the expression needs to change as I am reading web tier stuff from the model layer but I will fix this later) I then generated a java class for my EO. And added the following overriden method to my newly created java class. protected StringBuffer buildDMLStatement(int i, AttributeDefImpl[] attributeDefImpl,   AttributeDefImpl[] attributeDefImpl2, AttributeDefImpl[] attributeDefImpl3, boolean b) {   StringBuffer statement = super.buildDMLStatement(   i, attributeDefImpl, attributeDefImpl2, attributeDefImpl3, b); return new StringBuffer(StringUtils.replace(statement.to...

Util code

public static MethodExpression getMethodExpression( String expr, Class returnType, Class[] argTypes){ FacesContext fc = FacesContext.getCurrentInstance(); ELContext elctx = fc.getELContext(); ExpressionFactory elFactory = fc.getApplication().getExpressionFactory(); return elFactory.createMethodExpression( elctx, expr, returnType, argTypes); } public static javax.faces.el.MethodBinding getMethodBinding( String expr, Class[] argTypes){ FacesContext fc = FacesContext.getCurrentInstance(); ELContext elctx = fc.getELContext(); return fc.getApplication().createMethodBinding(expr, argTypes); } SetPropertyListener listener = new SetPropertyListener( ActionEvent.class.getName()); listener.setFrom(link.getRoute()); listener.setValueExpression("to", JSFUtils.getValueExpression("#{pageFlowScope.route}", String.class)); action.addActionListener(listener); AdfFacesContext.getCurrentInstance().getPageFlowScope() .put("route", lin...

MANIFEST.MF merge JDeveloper for an executable jar

Goto your project > properties. Then click on deployment in the menu. Edit or add a jar deployment profile. Fill in the details under jar options (select Include manifest and give it a main class name) Also remember that the merge functionality only works with a BLANK line at the end of the merge file. REALLY this caught me. My merge file contents: Class-Path: commons-codec-1.3.jar [...empty line here CRLF...]