Skip to Content

When it comes to transforming XML, I’m a huge fan of XSLT. There is a fairly steep learning curve to climb, but once you’ve done so, the power and expressiveness of the language is unmatched. Luckily, HCI supports XSLT mappings in your integration flows. As for the HCI developer tools, the Eclipse add-on offers full support for XSLT, but in the Web UI, XSLT is still nowhere to be seen. Expect this to change, though, as SAP continues to add features to the Web UI.

In this blog I will take a peek under the hood of the XSLT processor running in HCI, to see what we can learn about it.

Peeking under the hood

So HCI supports XSLT, which is great, because XSLT – like bow ties – is cool. But which processor is performing the XML transformations behind the scenes? To answer this, we can utilise XSLT’s system-property function to learn more about the underlying processor. The function takes a property name as its only input, and returns the value of that property. The following properties must be supported, as per the W3C specification:

  • xsl:version (the supported XSLT version)
  • xsl:vendor (the processor’s implementer)
  • xsl:vendor-url (the URL of the implementer’s web site)
  • xsl:product-name (the processor’s product name)
  • xsl:product-version (the version string of the product)
  • xsl:is-schema-aware (whether the processor is schema-aware)
  • xsl:supports-serialization (whether the processor supports the serialization feature)
  • xsl:supports-backwards-compatibility (whether the processor supports earlier versions of XSLT and XPath)

Right, let’s put all of these in an XSLT 2.0 stylesheet and run it through HCI’s processor. First, the stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

  <xsl:variable name="properties" select="(
    'xsl:version', 
    'xsl:vendor', 
    'xsl:vendor-url', 
    'xsl:product-name', 
    'xsl:product-version', 
    'xsl:is-schema-aware', 
    'xsl:supports-serialization', 
    'xsl:supports-backwards-compatibility')"/>

  <xsl:template match="/">
    <system-properties>
      <xsl:for-each select="$properties">
        <xsl:variable name="prop" select="."/>
        <xsl:element name="{substring-after($prop, ':')}">
          <xsl:value-of select="system-property($prop)"/>
        </xsl:element>
      </xsl:for-each>
    </system-properties>
  </xsl:template>

</xsl:stylesheet>

Executing this stylesheet in HCI, I get the following output:

<system-properties>
   <version>2.0</version>
   <vendor>Saxonica</vendor>
   <vendor-url>http://www.saxonica.com/</vendor-url>
   <product-name>SAXON</product-name>
   <product-version>HE 9.5.1.5</product-version>
   <is-schema-aware>no</is-schema-aware>
   <supports-serialization>yes</supports-serialization>
   <supports-backwards-compatibility>yes</supports-backwards-compatibility>
</system-properties>

This tells us that the XSLT 2.0 processor in HCI is Saxon-HE, the open-source version of the Saxon processor, specifically version 9.5.1.5 at the time of writing.

What does schema-aware mean anyway?

You might have noticed from the system-property output, that the open-source version of Saxon is not schema-aware. But what does that mean, exactly? Two things:

  1. It cannot validate the stylesheet’s input and output using XML Schema
  2. It cannot use data types defined in XML Schema

The first point doesn’t really matter in HCI, since we’re able to validate before and after the XSLT mapping using the XML Validator step anyway. The consequence of the second point is that you cannot create e.g. function parameters and variables with types, that are defined in XML Schema. You can of course still use the built-in types (xs:string, xs:integer et al).

Java extensions in Saxon-HE

The Saxon XSLT processor supports two mechanisms for executing Java code from inside a stylesheet: Reflexive extension functions and integrated extension functions. Unfortunately, neither is available to us in HCI. In the following I will briefly explain why that is the case. With XSLT 2.0, Java extensions are not as important as in XSLT 1.0, though. With user-defined functions and a much larger number of built-in functions available in XSLT 2.0, many problems can be solved directly in XSLT without resorting to external code.

Reflexive extension functions

This is the easier but more limited mechanism of the two. In the following example, the static pow method of class java.lang.Math is called with the parameters 2 and 8:

<xsl:value-of select="math:pow(2,8)" xmlns:math="java:java.lang.Math"/>

However, reflexive extension functions are not supported in Saxon-HE, the specific version of Saxon running in HCI.

Integrated extension functions

Integrated extension functions are more powerful, but require a bit more work. They are Java classes that you write, which means they can contain more complicated logic than is possible with reflexive extension functions. They also let you manage the conversion between XPath and Java types. However, there is a problem: Integrated extension functions must either be registered programmatically with the processor or added to a Saxon configuration file, and neither is possible in HCI.

To report this post you need to login first.

4 Comments

You must be Logged on to comment or reply to a post.

  1. Hemachandan A S

    Hi Morten,

    Useful blog and currently working to get external parameters in xslt mapping with below code but its not working so any suggestions?

    <xsl:param name=”external_location” select=”getProperties(Job_Location)” />

     

    Thanks,

    Chandan

    (1) 
  2. Sriprasad Shivaram Bhat

    Hello Morten,

    Its possible to set and get exchange properties inside XSLT  .

    How to get:

    https://answers.sap.com/questions/341836/hci-xslt-get-property-value.html?childToView=340091#answer-340091

    How to set:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:hci="http://sap.com/it/" exclude-result-prefixes="hci">
    
    	<xsl:param name="exchange"/>
    	<xsl:param name="Param1"/>
    	<xsl:param name="Param3"/>
    
    	<xsl:output method="xml" encoding="UTF-8" indent="no" />
    
    	<xsl:template match="/">
    		
    		<xsl:value-of select="hci:setProperty($exchange, 'Param2', $Param1)"/>
    		<xsl:value-of select="hci:setProperty($exchange, 'Param3', '222222')"/>
    		<xsl:value-of select="hci:setHeader($exchange, 'Param1', '1234567890')"/>
    
    		<Test1/>
    
    	</xsl:template>
    
    </xsl:stylesheet>

    Regards,

    Sriprasad Shivaram Bhat

    (1) 

Leave a Reply