Introduction to XSLT 2.0
Lionel
Villard, IBM Watson
History
- November 16th, 1999: XSL Transformation (XSLT) 1.0 becomes a W3C
recommendation
- Transformation language based on DSSSL
- Designed to be part of XSL
- Based on XML Path language (XPath) 1.0
- October 15th, 2001: EXtensible Stylesheet Language 1.0 becomes a
W3C recommendation
- November 12th 2003: Latest XSLT 2.0 public working draft
XSLT 1.0: Fundamental concepts
- Designed to transform document structure
- Node renaming, moving, re-ordering, etc
- Limitation: transforming document content is cumbersome
- Based on two processing models
- Source driven (push) : template pattern
- Target driven (pull) : node selection
- Borrow some functional language aspects
- Variables are immutable
- Template can be seen as function
- No high-order function
- Few types: Numeric, boolean, string, node and nodeset
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
- Based on common value
|

|
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
- Regular expression: <xsl:analyse-string
select="expression" regex="regex">
- Actions can be associated to
matching
substring and non matching
substring
- The function regex-group()
capture groups
- => Transformating document content becomes
better<><>
<><>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
- User-defined function in XSLT: <xsl:function
...>
<xsl:function name="str:reverse" as="xs:string"> ... </xsl:function>
... <xsl:value-of select="str:reverse('reverse this')"/>
- Multiple output documents <xsl:result-document
...>
- Template instantiable in multiple modes #current, #all,
#default
- Match the next template in priority order <xsl:next-match>
- Tunnel parameters
- A *LOT* of new functions (> 200) (see http://www.w3.org/TR/xquery-operators/)
XSLT 2.0: Fundamental changes
- Enhanced data-model
- Nodeset is generalized: welcome sequence of items (node or atomic value)
- Result tree fragment are generalized: welcome temporary tree
- Result tree fragment was read-only
- Type-system based on XML Schema
- More types: date and time.
- Numeric matches now the decimal, integer, double or float
types
- Types are "optional"
- Basic XSLT processor: almost the same as XSLT 1.0 with some
additionnal built-in types
- All built-in types defined in XML Schema (plus few more)
- Template can be typed and validated at runtime
What's about XQuery 1.0 ?
- XQuery 1.0 and XSLT 2.0 are the same!! ... well not exactly
- Same semantic but different users => different requirements
- Relatively small queries, huge input sources
- Performance against many many source documents is
critical
- Stylesheet can be big (docbook)
- Performance has been less of a focus at the language design
level
- Other differences:
- No serialization parameters in XQuery
- Regular expression more powerful in XSLT
- More functions to manipulate dates in XSLT
- Better typechecking in XQuery
Conclusion