14 Designing XSL Subtemplates

This chapter describes how to create XSL subtemplates to create reusable advanced functionality for your RTF templates.

This chapter includes the following sections:

14.1 Understanding XSL Subtemplates

An XSL subtemplate is an XSL file that consists of one or more <xsl:template> definitions, each containing a block of formatting or processing commands. When uploaded to BI Publisher as a Sub Template object in the Catalog, this XSL file can be called from other RTF templates to execute the formatting or processing commands.

XSL subtemplates can handle complex data and layout requirements. Use XSL subtemplates to transform the data structure for a section of a report (for example, for a chart) or to create a style sheet to manage a complex layout.

14.1.1 Where to Put XSL Code in the RTF Main Template

When you call the XSL subtemplate within a main RTF subtemplate, you use XSL commands. You must put this code inside a BI Publisher field (or Microsoft Word form field). You cannot enter XSL code directly in the body of the RTF template.

For more information on inserting form fields in an RTF template see Section 5.4.1, "Inserting a Field."

14.2 Process Overview for Creating and Implementing XSL Subtemplates

Creating and implementing an XSL subtemplate consists of the following steps:

  1. Create the XSL file that contains the common components or processing instructions to include in other templates.

    An XSL sub template consists of one or more XSL template definitions. These templates contain rules to apply when a specified node is matched.

  2. Create the calling or "main" layout that includes a command to "import" the subtemplate to the main template and a command to apply the XSL subtemplate to the appropriate data element.

  3. Upload the main template to the report definition and create the Sub Template object in the catalog.

14.3 Creating an XSL Subtemplate File

Enter the instructions in an editor that enables you to save the file as type ".xsl". An XSL subtemplate consists of one or more XSL template definitions. These templates contain rules to apply when a specified node is matched.

The syntax of the subtemplate definition is as follows:

<xsl:template
  name="name" 
  match="pattern" 
  mode="mode" 
  priority="number">
<!--Content:(<xsl:param>*,template) -->
</xsl:template>

Table 14-1 describes the components of the template declaration.

Table 14-1 Components of the Template Declaration

Component Description

xsl:template

The xsl:template element is used to define a template that can be applied to a node to produce a desired output display.

name="name"

Optional. Specifies a name for the template.

Note: If this attribute is omitted, a match attribute is required.

match="pattern"

Optional. The match pattern for the template.

Note: If this attribute is omitted a name attribute is required.

priority="number"

Optional. A number which indicates the numeric priority of the template. It is possible that more than one template can be applied to a node. The highest priority value template is always chosen. The value ranges from -9.0 to 9.0.


Example:

<xsl:template match="P|p">
  <fo:block white-space-collapse="false" padding-bottom="3pt" linefeed-treatment="preserve">
     <xsl:apply-templates select="text()|*|@*"/>
  </fo:block>
</xsl:template>

<xsl:template match="STRONG|B|b">
   <fo:inline font-weight="bold">
     <xsl:apply-templates/>
   </fo:inline>
</xsl:template>

14.4 Calling an XSL Subtemplate from the Main Template

To implement the subtemplate in the main template, make two entries in the main template:

First, import the subtemplate file to the main template. The import syntax tells the BI Publisher engine where to find the Sub Template in the catalog.

Second, enter a call command to render the contents of the subtemplate at the position desired.

14.4.1 Importing the Subtemplate

Enter the import command anywhere in the main template prior to the call template command as follows:

<?import:xdoxsl:///{path to subtemplate.xsb}?>

where

path to subtemplate.xsb is the path to the subtemplate .xsb object in the catalog.

For example:

<?import:xdoxsl:///Executive/Financial Reports/mySubtemplate.xsb?>

14.4.2 Calling the Subtemplate

The template statements that you defined within the XSL subtemplate file are applied to data elements. There are two ways you can call a template defined in the imported XSL subtemplate:

14.4.3 Passing Parameters to an XSL Subtemplate

To pass parameters to the XSL subtemplate:

  1. Declare the parameter in the <xsl:template> definition, as follows:

    <xsl:template name="templateName" match="/">
       <xsl:param name="name" />
    </xsl:template>
    
  2. Then call this template using the following syntax:

    <xsl:call-template name="templateName">
      <xsl:with-param name="name" select="expression">
        <?--- Content:template -->
      </xsl:with-param>
    </xsl:call-template>
    

14.5 Creating the Sub Template Object in the Catalog

To upload the subtemplate file:

  1. On the global header click New and then click Sub Template. This launches an untitled Sub Template page.

  2. In the Templates region, click Upload to launch the Upload Template File dialog.

  3. Browse for and select the subtemplate file.

    • Type: Select xsl for an XSL subtemplate file.

    • Locale: Select the appropriate locale for the subtemplate file.

  4. Click Upload.

    The subtemplate file is displayed in the Templates region as the locale name that you selected (for example: en_US).

  5. Click Save. In the Save As dialog choose the catalog folder in which to save the Sub Template. Enter the Name and click Save. Figure 14-1 shows a Sub Template named "My Subtemplate".

The Sub Template object is saved with the extension ".xsb". Use the Name that you choose here with the .xsb extension when you import the Sub Template to the report (for example: MySubtemplate.xsb).

Translations are not supported for XSL Sub Templates.

14.6 Example Uses of XSL Subtemplates

The following are examples of formatting that can be achieved in a report by using XSL subtemplates:

14.6.1 Handling XML Data with HTML Formatting

If you have XML data that already contains HTML formatting and you want to preserve that formatting in the report, then you can preserve that formatting by using an XSL subtemplate to map the HTML formatting commands to XSL equivalents that can be handled by BI Publisher.

Note that the HTML must be in XHTML format. This means that all HTML tags must have start and end tags in the data. For example, if the data uses a simple <BR> for a break, then you must add the closing </BR> before you can use this solution.

Following is some sample data with HTML formatting:

<DATA>
  <ROW>
    <PROJECT_NAME>Project Management</PROJECT_NAME>
    <PROJECT_SCOPE>
      <p>Develop an application to produce <i>executive-level summaries</i> and detailed project reports. The application will allow users to: </p>
       <p>Import existing MS Project files </p>
       <p>Allow the user to map file-specific resources to a central database entities (i.e., people) and projects; </p>
       <p>Provide structured output that can be viewed by staff and executives. </p>
   </PROJECT_SCOPE>
   <PROJECT_DEFINITION><b>Information about current projects is not readily available to executives.</b> Providing this information creates a reporting burden for IT staff, who may already maintain this information in Microsoft Project files. </PROJECT_DEFINITION>
  </ROW>
</DATA>

Note in this sample the following HTML tags:

  • <p> - paragraph tag

  • <i> - italics tag

  • <b> - bold tag

Assume a report requirement to display this to retain the formatting supplied by these tags as shown in Figure 14-2.

Figure 14-2 Sample HTML Tags

Description of Figure 14-2 follows
Description of "Figure 14-2 Sample HTML Tags"

The following subtemplate uses XSL syntax to match the three HTML tags in the XML data. The template then replaces the matched HTML string with its XSLFO equivalent.

<xsl:template match="P|p">
 <fo:block white-space-collapse="false" padding-bottom="3pt" linefeed-treatment="preserve">
  <xsl:apply-templates select="text()|*|@*"/> 
 </fo:block>
</xsl:template>

<xsl:template match="STRONG|B|b">
        <fo:inline font-weight="bold">
                <xsl:apply-templates/>
        </fo:inline>
</xsl:template>

<xsl:template match="EM|I|i">
        <fo:inline font-style="italic">
                <xsl:apply-templates/>
        </fo:inline>
</xsl:template>

To use this XSL syntax:

  1. Upload this XSL subtemplate file to the BI Publisher catalog location: Shared Folders/Projects. Save this subtemplate file as "htmlmarkup.xsb".

  2. In the main template enter the following to import the subtemplate file:

    <?import:xdoxsl:///Projects/htmlmarkup.xsb?>
    
  3. For each field that has HTML markup, call the xsl apply-template command. In this example, there are two fields:

    <xsl:apply-templates select="PROJECT_SCOPE"/>
    <xsl:apply-templates select="PROJECT_DEFINITION"/>
           
    

    Figure 14-3 shows the field definitions in the template.

    Figure 14-3 Field Definitions

    Description of Figure 14-3 follows
    Description of "Figure 14-3 Field Definitions"

    The command tells the processor to apply all templates to the value of the element PROJECT_SCOPE and PROJECT_DEFINITION. It then cycles through the subtemplate functions looking for a match.

14.6.2 Dynamically Applying Formatting to a Portion of Data

This application of subtemplates is useful for documents that require chemical formulae, mathematical calculations, or superscripts and subscripts.

For example, in the sample XML data below CO2 is expected to display as CO2 and H2O is expected to display as H2O.

<ROWSET> 
  <ROW> 
    <FORMULA>CO2</FORMULA> 
  </ROW> 
  <ROW> 
   <FORMULA>H2O</FORMULA> 
  </ROW>
</ROWSET>

This can be achieved by using an XSL subtemplate. Using XSL syntax you can define a template with any name, for example, "chemical_formatter" that accepts the FORMULA field as a parameter, and then read one character at a time. It compares the character with 0 - 9 digits, and if there is a match, then that character is subscripted using the following XSL FO syntax:

<fo:inline baseline-shift="sub" font-size="75%">

Here is sample code for the XSL template statement:

<xsl:template name="chemical_formatter"> 
<! -  accepts a parameter e.g. H2O  - > 
<xsl:param name="formula"/> 
<! -  Takes the first character of the string and tests it to see if it is a number between 0-9 - > <xsl:variable name="each_char" 
select="substring($formula,1,1)"/> 
<xsl:choose> 
   <xsl:when test="$each_char='1' or $each_char='2' 
   or $each_char='3' or $each_char='4' or $each_char='5' 
   or $each_char='6' or $each_char='7' or $each_char='8' 
   or $each_char='9' or $each_char='0'"> 
   <! -  if it is numeric it sets the FO subscripting properties  - > 
     <fo:inline baseline-shift="sub" font-size="75%"> 
        <xsl:value-of select="$each_char"/> 
     </fo:inline> 
   </xsl:when> 
   <xsl:otherwise> 
   <! -  otherwise the charater is left as is  - > 
       <fo:inline baseline-shift="normal"> 
         <xsl:value-of select="$each_char"/> 
       </fo:inline> 
   </xsl:otherwise> 
 </xsl:choose> 
 <! -  test if there are other chars in the string, if so the recall the template  - >
   <xsl:if test="substring-after($formula,$each_char) !=''"> 
      <xsl:call-template name="chemical_formater"> 
        <xsl:with-param name="formula"> 
           <xsl:value-of select="substring-after($formula,$each_char)"/> 
        </xsl:with-param> 
     </xsl:call-template> 
   </xsl:if> 
</xsl:template>

To use this XSL template statement:

  1. Save this file as chemical.xsl.

  2. Follow the instructions in Section 12.4, "Creating the Sub Template Object in the Catalog." Assume that you name the Sub Template "Chemical" (it is saved as Chemical.xsb) and place it in the following location: Shared Folders/Subtemplates.

  3. In the main RTF template enter the import syntax:

    <?import:xdoxsl:///Subtemplates/Chemical.xsb?>
    
  4. To render the XSL code in the report, create a loop over the data and in the VALUE field use:

    <xsl:call-template name="chemical_formatter">
    <xsl:with-param name="formula" select="VALUE"/> </xsl:call-template>
    

This calls the formatting template with the FORMULA value that is, H2O. Once rendered, the formulae are shown as expected: H2O.