Formatting HTML with Templates
Happy New Year everyone ... back on the horse again, I'll try and stay on this time!
I have had several requests on how to handle HTML formatted XML in their templates, to save you time finding my email and me answering here's the solution. When there is HTML formatted data in the source XML it needs to be converted to the XSLFO format prior to being put into the final document otherwise the raw HTML will be inserted so something like
<B>This is bold text</B>
needs to be converted to its XSLFO equivalent
<fo:inline font-weight="bold">This is bold text</fo:inline>
We can do this reasonably simply but their is one caveat. The HTML must be in the XHTML format i.e. <BR> is not going to work it needs to be <BR></BR> for a new line. So, if you have HTML in your data you'll need to clean it up to get XHTML using something like JTidy or Tidy. Once you have the cleaned up XHTML you're ready to convert it to the XSLFO equivalent.
To do this, the easiest way is to use a sub template, Im advocating that because you are likely to need to use the functionality across multiple templates. The sub template is going to be written in XSLFO, not the easiest language in the world but I have posted a sample template that handles much of the common HTML for you. Its basically a set of functions that accept the input and convert it if necessary to XSLFO. Take a look at the template and you'll see a series of functions with a similar format:
<xsl:template match="STRONG|B|b">The first line is looking for 'STRONG', 'B' or 'b' to match on the HTML markup for bold. The template then replaces the matched HTML string with its XSLFO equivalent. The posted sample has some more complex examples handling lists, bullets, etc. So thats the sub template, now we need to register and call in it in the main template.
<fo:inline font-weight="bold">
<xsl:apply-templates />
</fo:inline>
</xsl:template>
In the top of the main template we register our interest in the sub template thus:
<?import:file:///c:temphtmlmarkup.xsl?>Im using a the file URI to be able to run it on my desktop for the sample but you can use a full URL if you are using the Enterprise release or the XMLP URI reference if you are using EBS, see the user guide on referencing sub templates.
Our main template is now aware of the sub template, we now need to call the functions therein to get our html converted. For each field in our RTF template that might have HTML markup we need to call for the markup functions to be applied this requires a simple call:
<xsl:apply-templates select="PROJECTSCOPE"/>
Sadly we have to resort to XSL as the XMLP aliases do not support calling a template on a data element yet. This command tells the processor to apply all templates to the value of the element PROJECTSCCOPE. It will then cycle through the sub template functions looking for a match. You need to do this for all the fields that may have HTML markup in the XML data.
Now when you run the template against the XML the HTML markup will be converted to XSLFO markup et voila you have correctly formatted text in your output. You can get the complete example here.
Happy Templating