This topic describes how to create XSL subtemplates to create reusable advanced functionality for your RTF templates.
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.
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 Inserting a Field.
You must follow this process when working with XSL sub templates.
Creating and implementing an XSL sub template consists of the following steps:
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>
The following table describes the 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. If this attribute is omitted, a match attribute is required. |
match="pattern" |
Optional. The match pattern for the template. 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>
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.
Enter the import command anywhere in the main template prior to the call template command as shown here.
<?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?>
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.
By matching the data content with the match criteria:
<xsl:apply-templates select="data_element"/>
This method applies all the templates that are defined in the XSL subtemplate to the data_element specified. Based on the data content of data_element, appropriate functions in those templates are applied. See the following use case for a detailed example: Handling XML Data with HTML Formatting.
By calling a template by name:
<xsl:call-template name="templateName"/>
This method calls the template by name and the template executes, similar to a function call. Here also parameters can be passed to the template call, similarly to an RTF subtemplate. See Passing Parameters to an XSL Subtemplate.
See the following use case for a detailed example: Dynamically Applying Formatting to a Portion of Data.
Follow these steps to upload the sub template file.
To upload the sub template file:
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.
These are examples of formatting that can be achieved in a report by using XSL subtemplates.
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 the following figure:
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>
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>
This calls the formatting template with the FORMULA value that is, H2O. Once rendered, the formulae are shown as expected: H2O.