So XSLT 2.0 processors can operate not only on XML but on anything that can be made to look like XML:
The current versions are defined by the XSLT 1.0, 2.0 and 3.0 specifications:
(Wikipedia, XSLT)
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person username="JS1">
<name>John</name>
<family-name>Smith</family-name>
</person>
<person username="MI1">
<name>Morka</name>
<family-name>Ismincius</family-name>
</person>
</persons>
(Wikipedia, XSLT)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/persons">
<root>
<xsl:apply-templates select="person"/>
</root>
</xsl:template>
<xsl:template match="person">
<name username="{@username}">
<xsl:value-of select="name" />
</name>
</xsl:template>
</xsl:stylesheet>
(Wikipedia, XSLT)
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name username="JS1">John</name>
<name username="MI1">Morka</name>
</root>
Xalan: an open source XSLT 1.0 processor from the Apache Software Foundation available stand-alone and for Java and C++. Integrated into Java SE.
Safari, Chrome, Firefox, Opera and Internet Explorer all support XSLT 1.0. None supports XSLT 2.0 natively, although the third party products like Saxon-CE (Saxon-Client Edition) and Frameless can provide this functionality. Browsers can perform on-the-fly transformations of XML files and display the transformation output in the browser window. This is done either by embedding the XSL in the XML document or by referencing a file containing XSL instructions from the XML document. The latter may not work with Chrome because of its security model.
Template (xsl:template) is a specification which node should be rewriten and how (into what):
After processing of the source node, the processing continues at the nodes selected by xsl:apply-templates select=" <xpath expression> ".
Motivation: Modes allow a parallel set of templates with the same patterns match, but used for different purposes, for example:
With explicit node selection: when using xsl:apply-templates with explicit selection of nodes for further processing by using the select attribute.
<xsl:template match="*|/">
<xsl:apply-templates/>
<xsl:template>
<xsl:template match="*|/" mode="...">
<xsl:apply-templates mode="..."/>
<xsl:template>
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
<xsl:template>
<xsl:template match="processing-instruction()|comment()" />
<link ref="a_link_href">
...
</link>
Template
<xsl:template match="link">
<a href="#{@ref}"> ... </a>
</xsl: template>
Transforms the link to a (possibly HTML) a element, the href attribute value is composed of # and the value of the original ref attribute.
<a href="#a_link_href"> ... </a>
Input:
<generate element-name="myelement"> ... </generate>
Template:
<xsl:template match="generate">
<xsl:element name="{@element-name}">
<xsl:attribute name="id">ID1</xsl:attribute>
</xsl:element>
</xsl:template>
Solution: Use branching in the template - either
<bread price="50"> ... </bread>
<xsl:template match="bread">
<p>
<xsl:if test="@price > 30">
<span class="expensive">Expensive </span>
</xsl:if>bread - price <xsl:value-of select="@price"/> CZK</p>
</xsl:template>
<bread price="12"> ... </bread>
<bread price="19"> ... </bread>
<bread price="30"> ... </bread>
<xsl:template match="bread">
<xsl:choose>
<xsl:when test="@price > 30">
<span class="expensive">Expensive</span>
</xsl:when>
<xsl:when test="@price < 10">
<span class="strangely-cheap">Suspiciously cheap</span>
</xsl:when>
<xsl:otherwise>
<span class="normal-price">Normal</span>
</xsl:otherwise>
</xsl:choose> bread - price <xsl:value-of select="@price"/> CZK
</xsl:template>
<grocery>
<bread price="12"> ... </bread>
<bread price="19"> ... </bread>
<bread price="30"> ... </bread>
</grocery>
<xsl:template match="grocery">
<xsl:for-each select="bread">
<p> bread - price <xsl:value-of select="@price"/> CZK </p>
</xsl:for-each>
</xsl:template>
The call can also specify the parameters if declared at definition:
For either (or both):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="group">
<xsl:text>Group </xsl:text>
<xsl:number count="group" level="multiple"/>
<xsl:text>
</xsl:text>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="person">
<xsl:number count="group" level="multiple" format="1.1.1."/>
<xsl:number count="person" level="single" format="1 "/>
<xsl:value-of select="@name"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
<people>
<group>
<person name="Al Zehtooney" age="33" sex="m" smoker="no"/>
<person name="Brad York" age="38" sex="m" smoker="yes"/>
</group>
<group>
<person name="Greg Sutter" age="40" sex="m" smoker="no"/>
<person name="Harry Rogers" age="37" sex="m" smoker="no"/>
<group>
<person name="John Quincy" age="43" sex="m" smoker="yes"/>
<person name="Kent Peterson" age="31" sex="m" smoker="no"/>
</group>
<person name="John Frank" age="24" sex="m" smoker="no"/>
</group>
</people>
Group 1
1.1 Al Zehtooney
1.2 Brad York
Group 2
2.1 Greg Sutter
2.2 Harry Rogers
Group 2.1
2.1.1 John Quincy
2.1.2 Kent Peterson
2.3 John Frank
Good for simple try-and-see:
With XSLT 2.0 support:
All recent NetBeans version allow to launch XSLT just by:
/