Tuesday, September 12, 2023

XSLT 3.0, XPath 3.1 and XalanJ

It's been a while that, I've written a blog post here. I've few new updates, about the work which XalanJ team has been doing over the past few months, that I wish to share with the XML community.

XalanJ project, provides XSLT and XPath processors that are written with Java language. An XSLT processor transforms an XML input document (or even only text files), into other formats like XML, HTML and text.

XalanJ project, has released a new version (2.7.3) of XalanJ on 2023-04-01. This XalanJ release, essentially is a bug fix release over the previous release. The XalanJ 2.7.3 release was extensively tested by XalanJ team, and it has very good compliance with XSLT 1.0 and XPath 1.0 specs.

Since Apr 2023, XalanJ team has been working to develop implementations of XSLT 3.0 and XPath 3.1 language specifications. These XalanJ codebase changes are currently not released by XalanJ team, but are available on XalanJ dev repos branch.

I further wish to write about, XSLT 3.0 user-defined callable component implementation enhancements within XalanJ, that should be available within one of the future XalanJ release. The callable components within a programming language are, essentially functions and procedures. XSLT 1.0 language has only one kind of user-defined callable component, which is written with an XML element name xsl:template.

XSLT 3.0 provides another kind of user-defined callable component, defined with an XML element name xsl:function. An XSLT instruction xsl:function was first made available within XSLT 2.0 language. A user-defined function present within an XSLT stylesheet, may be called within an XPath expression.

Following is an example of XSLT 3.0 stylesheet, that makes use of an xsl:function element,

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                         xmlns:ns0="http://ns0"
                         exclude-result-prefixes="ns0"
                         version="3.0">
    
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="/">       
         <result>
             <one>
                 <xsl:value-of select="ns0:func1(6, 5, true(), false())"/>
             </one>
             <two>
         <xsl:value-of select="ns0:func1(2, 5, true(), false())"/>
             </two>
         </result>
    </xsl:template>
    
    <xsl:function name="ns0:func1">
         <xsl:param name="val1"/>
         <xsl:param name="val2"/>
         <xsl:param name="a"/>
         <xsl:param name="b"/>
       
         <xsl:value-of select="if ($val1 gt $val2) then ($a and $b) else ($a or $b)"/>
    </xsl:function>
    
</xsl:stylesheet>

The above cited XSLT stylesheet, defines an user-defined function named "func1" bound to the specified non-null XML namespace. This function definition requires four arguments with a function call, and produces a boolean result based on few logical conditions.

The above cited XSLT stylesheet, produces following output with XalanJ,

<?xml version="1.0" encoding="UTF-8"?><result>
  <one>false</one>
  <two>true</two>
</result>

XPath 3.1 provides a new kind of callable component (that wasn't available with XPath 1.0), which is an inline function definition which when compiled by an XPath processor, produces an XPath data model (XDM) function item.

An XPath 3.1 function item, may be called via an XPath dynamic function call expression.

Following is an XSLT 3.0 stylesheet, that specifies an XPath inline function expression, and is an alternate solution to above cited XSLT stylesheet,

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                         version="3.0">
    
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:variable name="func1" select="function($val1, $val2, $a, $b) { if ($val1 gt $val2) then ($a and $b) else ($a or $b) }"/>
    
    <xsl:template match="/">       
         <result>
             <one>
                   <xsl:value-of select="$func1(6, 5, true(), false())"/>
             </one>
             <two>
          <xsl:value-of select="$func1(2, 5, true(), false())"/>
             </two>
         </result>
    </xsl:template>
    
</xsl:stylesheet>

The above cited XSLT stylesheet, specifies an XPath inline function expression assigned to an XSLT variable "func1". This makes, XPath expressions like $func1(..) as function calls (which are termed as dynamic function calls by XPath 3.1 language).

The above cited XSLT stylesheet, produces an output with XalanJ, which is same as with an earlier cited stylesheet.

Its perhaps also interesting to discuss and analyze, which of the above mentioned XSLT callable components approaches an XSLT stylesheet author should choose?

An XPath 3.1 inline function expression is an *XPath expression*, therefore its function body is limited to have XPath syntax only.

Whereas, an xsl:function is an XSLT instruction (which may be invoked as a function call, from within XPath expressions). The xsl:function function's body may have significantly complex logic (with any permissible XSLT syntax and XPath expressions) as compared to XPath inline function expressions.

To conclude, I believe that, when using XSLT 3.0 and XPath 3.1, we have following three main kinds of user-defined callable components which may be used by XSLT stylesheet authors,

1) xsl:template   (which is very important within an XSLT stylesheet, and is the core of an XSLT stylesheet)

2) xsl:function

3) XPath inline function expression

That's all I wished to say within this blog post.