Using Caché XML Tools
Performing XSLT Transformations
[Back] [Next]
   
Server:docs2
Instance:LATEST
User:UnknownUser
 
-
Go to:
Search:    

XSLT (Extensible Stylesheet Language Transformations) is an XML-based language that you use to describe how to transform a given XML document into another XML or other “human-readable” document. You can use classes in the %XML.XSLT and %XML.XSLT2 packages to perform XSLT 1.0 and 2.0 transforms. This chapter discusses the following topics:

Note:
The XML declaration of any XML document that you use should indicate the character encoding of that document, and the document should be encoded as declared. If the character encoding is not declared, Caché uses the defaults described in Character Encoding of Input and Output,” earlier in this book. If these defaults are not correct, modify the XML declaration so that it specifies the character set actually used.
Overview of Performing XSLT Transformations in Caché
Caché supports XSLT 1.0 and XSLT 2.0. Note that XSLT 2.0 is not supported on OpenVMS.
To perform XSLT transformations, do the following:
  1. For XSLT 2.0, configure the XSLT Gateway Server, as described in the next section. Or use the default configuration.
    The gateway is not needed for transformations that use XSLT 1.0.
    Caché automatically starts the gateway when needed. Or you can manually start it.
  2. Optionally create a compiled style sheet and load it into memory. See Creating a Compiled Style Sheet,” later in this chapter.
    This step is useful if you intend to use the same style sheet repeatedly. This step, however, also consumes memory. Be sure to remove the compiled style sheet when you no longer need it.
  3. Call one of the applicable transform methods. See Performing an XSLT Transform,” later in this chapter.
Studio also provides a wizard that you can use to test XSLT transformations; this is described later in this chapter.
Configuring, Starting, and Stopping the XSLT 2.0 Gateway
When you perform XSLT 2.0 transformations, Caché uses the XSLT 2.0 Gateway, which in turn uses Java. To configure this gateway:
  1. Select Go.
    The system displays the [Home] > [Configuration] > [XSLT Gateway Server] page.
    The left area displays configuration details, and the right area displays recent activity.
  2. In the left area, optionally specify the following settings:
    This area also displays the current value of the JAVA_HOME environment variable.
    Note that you cannot edit any of these values while the gateway is running.
  3. If you have made changes, select Save to save them. Or select Reset to discard them.
  4. Optionally select Test to test your changes.
On this page, you can also do the following:
Creating a Compiled Style Sheet
If you intend to use the same style sheet repeatedly, you may want to compile it to improve speed. Note that this step consumes memory. Be sure to remove the compiled style sheet when you no longer need it.
To create a compiled style sheet:
For all these methods, the complete argument list is as follows, in order:
  1. source — The style sheet.
    For CreateFromFile(), this argument is the filename. For CreateFromStream(), this argument is a stream.
  2. compiledStyleSheet — The compiled style sheet, returned as an output parameter.
    This is an instance of the style sheet class (%XML.XSLT.CompiledStyleSheet or %XML.XSLT2.CompiledStyleSheet, as appropriate).
  3. errorHandler — An optional custom error handler to use when compiling the style sheet. See Customizing the Error Handling,” later in this chapter.
    For methods in both classes, this is an instance of %XML.XSLT.ErrorHandler.
The CreateFromFile() and CreateFromStream() methods return a status, which should be checked.
For example:
 //set tXSL equal to the OREF of a suitable stream
 Set tSC=##class(%XML.XSLT.CompiledStyleSheet).CreateFromStream(tXSL,.tCompiledStyleSheet)
 If $$$ISERR(tSC) Quit
Performing an XSLT Transform
To perform an XSLT transform:
These methods have similar signatures. The argument lists for these methods are as follows, in order:
  1. pSource — The source XML, which is to be transformed. See the table after this list.
  2. pXSL — The style sheet or compiled style sheet. See the table after this list.
  3. pOutput — The resulting XML, returned as an output parameter. See the table after this list.
  4. pErrorHandler — An optional custom error handler. See Customizing the Error Handling,” later in this chapter. If you do not specify a custom error handler, the method uses a new instance of %XML.XSLT.ErrorHandler (for both classes).
  5. pParms — An optional Caché multidimensional array that contains parameters to be passed to the style sheet. See Specifying Parameters for Use by the Stylesheet,” later in this chapter.
  6. pCallbackHandler — An optional callback handler that defines XSLT extension functions. See Adding and Using XSLT Extension Functions,” later in this chapter.
  7. pResolver — An optional entity resolver. See Performing Custom Entity Resolution,” later in this book.
For reference, the following table shows the first three arguments of these methods, compared side by side:
Comparison of XSLT Transform Methods
Method pSource (Input XML) pXSL (Style Sheet) pOutput(Output XML)
TransformFile() String that gives a file name String that gives a file name String that gives a file name
TransformFileWithCompiledXSLT() String that gives a file name Compiled style sheet String that gives a file name
TransformStream() Stream Stream Stream, returned by reference
TransformStreamWithCompiledXSLT() Stream Compiled style sheet Stream, returned by reference
TransformStringWithCompiledXSLT() String Compiled style sheet String that gives a file name
Examples
This section shows a couple of transformations, using the following code (but different input files):
  Set in="c:\0test\xslt-example-input.xml"
  Set xsl="c:\0test\xslt-example-stylesheet.xsl"
  Set out="c:\0test\xslt-example-output.xml"
  Set tSC=##class(%XML.XSLT.Transformer).TransformFile(in,xsl,.out)
  Write tSC 
Example 1: Simple Substitution
In this example, we start with the following input XML:
<?xml version="1.0" ?>
<s1 title="s1 title attr">
  <s2 title="s2 title attr">
    <s3 title="s3 title attr">Content</s3>
  </s2>
</s1>
And we use the following style sheet:
<?xml version="1.0"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:output method="xml" indent="yes"/>
 
<xsl:template match="//@* | //node()">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates select="node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="/s1/s2/s3">
<xsl:apply-templates select="@*"/>
<xsl:copy>
Content Replaced
</xsl:copy>
</xsl:template>  

</xsl:stylesheet>
In this case, the output file would be as follows:
<?xml version="1.0" encoding="UTF-8"?>
<s1 title="s1 title attr">
  <s2 title="s2 title attr">
    <s3>
Content Replaced
</s3>
  </s2>
</s1>
Example 2: Extraction of Contents
In this example, we start with the following input XML:
<?xml version="1.0" encoding="UTF-8"?>
<MyRoot>
   <MyElement No="13">Some text</MyElement>
   <MyElement No="14">Some more text</MyElement>
</MyRoot>
And we use the following style sheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1"   
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="text"
            media-type="text/plain"/>
<xsl:strip-space elements="*"/>

<!-- utilities not associated with specific tags -->
<!-- emit a newline -->
<xsl:template name="NL">
    <xsl:text>&#xa;</xsl:text>
</xsl:template>

<!-- beginning of processing -->

<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="MyElement">
    <xsl:value-of select="@No"/>
    <xsl:text>: </xsl:text>
    <xsl:value-of select="."/>
    <xsl:call-template name="NL"/>
</xsl:template>

</xsl:stylesheet>
In this case, the output file would be as follows:
13: Some text
14: Some more text
Additional Examples
Caché provides the following additional examples:
Customizing the Error Handling
When an error occurs, the XSLT processor executes the error() method of the current error handler, sending a message as an argument to that method. Similarly, when a fatal error or warning occurs, the XSLT processor executes the fatalError() or warning() method, as appropriate.
For all three of these methods, the default behavior is to write the message to the current device.
To customize the error handling of the Caché XSLT processor, you do the following:
  1. Create a subclass of %XML.XSLT.ErrorHandler. In this subclass, implement the error(), fatalError(), and warning() methods as needed.
    Each of these methods accepts a single argument, a string that contains the message sent by the XSLT processor.
    These methods do not return values.
  2. Then:
Specifying Parameters for Use by the Stylesheet
To specify parameters for use by the stylesheet, you create a Caché multidimensional array that contains the parameter names and values. You use this array in the argument list of the transform method you use.
This multidimensional array can have any number of nodes with following structure and value:
Node Value
arrayname("parameter_name") Value of the parameter named by parameter_name
Adding and Using XSLT Extension Functions
You can create XSLT extension functions in Caché and then use them within your style sheet. Specifically, your style sheet can use the evaluate function in the namespace http://extension-functions.intersystems.com
By default (and as an example), this function reverses the characters that it receives. Typically, however, the default behavior is not used, because you implement some other behavior. To simulate multiple separate functions, you pass a selector as the first argument and implement a switch that uses that value to choose the processing to perform.
Internally, the evaluate function is implemented as a method (evaluate()) in the XSLT callback handler.
To add and use XSLT extension functions, do the following:
  1. Create a subclass of %XML.XSLT.CallbackHandler. In this subclass, implement the evaluate() method as needed. See the following subsection.
  2. In the style sheet, declare the namespace to which the evaluate function belongs and use the evaluate function as needed. See the following subsection.
  3. When performing an XSLT transform, create an instance of your subclass and use it in the argument list of the transform method you use. See Performing an XSLT Transform.”
Implementing the evaluate Method
Internally, the code that calls the XSLT processor can pass any number of positional arguments to the evaluate method of the current callback handler, which receives them as an array that has the following structure:
Node Value
Args Number of arguments
Args(index) Value of the argument in the position index
The method has a single return value. The return value can be either:
Using evaluate in a Style Sheet
To use XSLT extension functions in an XSLT, you must declare the namespace of the extension functions in the XSLT stylesheet. For the InterSystems evaluate function, this namespace is http://extension-functions.intersystems.com.
The following example shows a style sheet that uses evaluate:
<?xml version="1.0"?>

<xsl:stylesheet 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
xmlns:isc="http://extension-functions.intersystems.com">

  <xsl:output method="xml" indent="yes"/>
 
  <xsl:template match="//@* | //node()">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates select="node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/s1/s2/s3">
  <xsl:apply-templates select="@*"/>
  <xsl:choose>
  <xsl:when test="function-available('isc:evaluate')">
  <xsl:copy>
  <xsl:value-of select="isc:evaluate(.)" disable-output-escaping="yes"/>
  </xsl:copy>
  </xsl:when>
  <xsl:otherwise>
  <xsl:value-of select="."/>
  </xsl:otherwise>
  </xsl:choose>
  </xsl:template> 

</xsl:stylesheet>
For a closer look at this example, see the source code for the Example3() method of %XML.XSLT.Transformer.
Using the XSL Transform Wizard
Studio provides a wizard that performs an XSLT transformation, which is useful when you want to quickly test a style sheet or your custom XSLT extension functions. To use this schema wizard:
  1. Specify the following required details:
  2. If you have created a subclass of %XML.XSLT.CallbackHandler that you want to use in this transformation, specify the following details:
    See Adding and Using XSLT Extension Functions,” earlier in this chapter.
  3. Select Finish.
    The bottom of the dialog box displays the transformed file. You can copy and paste from this area.
  4. To close this dialog box, select Cancel.