Introduction to XSLT 2.0

Lionel Villard, IBM Watson

History

XSLT 1.0: Fundamental concepts

XSLT 2.0: What's better, an example.

In XSLT 1.0:
<xsl:template match="@one-of" name="parse-one-of">
<xsl:param name="list" select="string(.)" />
<xsl:if test="$list">
<xsl:variable name="value"
select="substring-before($list, '|')" />
...
<!-- do something with $value -->
...
<!-- recursive call -->
<xsl:call-template name="parse-one-of">
<xsl:with-param name="list"
select="substring-after($list, '|')" />
</xsl:call-template>
</xsl:if>
</xsl:template>

In XSLT 2.0:

<xsl:for-each select="tokenize(@one-of, '|')">
<!-- do something with . -->
</xsl:for-each>

Overview of the new features  - Grouping

Grouping : <xsl:for-each-group ...>

  • Based on sequential position
    • by transitions at the start of each group
    • by transitions at the end of each group
    • by adjacent key values
  • Based on common value
Grouping example

Example: Grouping by common value

Input document:
<cities>
<city name="milan" country="italy" pop="5"/>
<city name="paris" country="france" pop="7"/>
<city name="munich" country="germany" pop="4"/>
<city name="lyon" country="france" pop="2"/>
<city name="venice" country="italy" pop="1"/>
</cities>
<table>
<tr>
<th>Country</th>
<th>City List</th>
<th>Population</th>
</tr>
<tr>
<td>italy</td>
<td>milan, venice</td>
<td>6</td>
</tr>
<tr>
<td>france</td>
<td>paris, lyon</td>
<td>9</td>
</tr>
<tr>
<td>germany</td>
<td>munich</td>
<td>4</td>
</tr>
</table>

Country City List Population
italy milan, venice 6
france paris, lyon 9
germany munich 4

Solutions

XSLT 1.0: Based on the Muenchian method.
<xsl:for-each select="cities/city[not(@country = preceding::*/@country)]">
<tr>
<td><xsl:value-of select="@country"/></td>
<td>
<xsl:for-each select="../city[@country = current()/@country]">
<xsl:value-of select="@name"/>
<xsl:if test="position() != last()">, </xsl:if>
</xsl:for-each>
</td>
<td><xsl:value-of select="sum(../city[@country = current()/@country]/@pop)"/></td>
</tr>
</xsl:for-each>

XSLT 2.0:

<xsl:for-each-group select="cities/city" group-by="@country">
<tr>
<td><xsl:value-of select="@country"/></td>
<td>
<xsl:value-of select="current-group()/@name" separator=", "/>
</td>
<td><xsl:value-of select="sum(current-group()/@pop)"/></td>
</tr>
</xsl:for-each-group>

An other new feature: Regular expression

<><>This example transforms dates of the form “12/8/2003” into ISO 8601 standard form: “2003-12-08”.
<xsl:analyze-string select="$date" regex="([0-9]+)/([0-9]+)/([0-9]{{4}})">
<xsl:matching-substring>
<xsl:number value="regex-group(3)" format="0001"/>
<xsl:text>-</xsl:text>
</xsl:matching-substring>
</xsl:analyse-string>

Overview of some others features

	<xsl:function name="str:reverse" as="xs:string"> ... </xsl:function>
... <xsl:value-of select="str:reverse('reverse this')"/>

XSLT 2.0: Fundamental changes

What's about XQuery 1.0 ?

Conclusion