XSLT: Difference between revisions

From miki
Jump to navigation Jump to search
Line 128: Line 128:
</source>
</source>
== Examples ==
== Examples ==
=== Simple <code><xsl:template></code> ===
TBC
{| class=wikitable width=100%
|-
|
{| width=100%
|-
| valign=top width=50% |
;XSLT file
<source lang=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="text" indent="no" encoding="UTF-8"/>

<xsl:param name="PARAM"/>

<xsl:template match="project">
<xsl:text/>This template will replace 'project' by a simple <xsl:value-of select="$PARAM"/><xsl:text/>
</xsl:template>

</xsl:stylesheet>
</source>
| valign=top |
;Source file
<source lang=xml>
<?xml version="1.0"?>
<project name="myproject">
<target name="myname"/>
</project>
</source>
|}
;Processed with
:<code>xsltproc -param PARAM "'text'" style.xsl source</code>
;output
<source lang=text>
This template will replace 'project' by a simple text
</source>
|}

=== Spaces and CR ===
{| class=wikitable width=100%
|-
|
{| width=100%
|-
| valign=top width=50% |
;XSLT file
<source lang=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="text" indent="no" encoding="UTF-8"/>

<xsl:param name="WORLD"/>

<xsl:template match="project">
<xsl:text>CR/spaces are preserved...
inside 'xsl:text'.</xsl:text>

<xsl:text> But spaces/CR between two tags are deleted.</xsl:text>
Except if ...
it contains non-blanks.
<xsl:text/>So better use empty text tags<xsl:text/>
<xsl:text/> to eat spaces/CR, while still using
... xslt <xsl:value-of select="$PARAM"/><xsl:text/>
</xsl:template>

</xsl:stylesheet>
</source>
| valign=top |
;Source file
<source lang=xml>
<?xml version="1.0"?>
<project name="myproject">
<target name="myname"/>
</project>
</source>
|}
;Processed with
:<code>xsltproc -param PARAM "'parameters.'" style.xsl source</code>
;output
<source lang=text>
CR/spaces are preserved...
inside 'xsl:text'. But spaces/CR between two tags are deleted.
Except if ...
it contains non-blanks.
So better use empty text tags to eat spaces/CR, while still using
... xslt parameters.
</source>
|}

=== Using entities ===
{| class=wikitable width=100%
|-
|
{| width=100%
|-
| valign=top width=50% |
;XSLT file
<source lang=xslt>
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY cr '<xsl:text xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
</xsl:text>'>
<!ENTITY space '<xsl:text xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> </xsl:text>'>
<!ENTITY param '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="$PARAM"/>'>
<!ENTITY entity '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="$ENTITY"/>'>
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project">
<xsl:text/>Use entities for special characters like<xsl:text/>
<xsl:text/>&cr;&cr;<xsl:text/>
carriage return
<xsl:text/>&cr;&cr;<xsl:text/>
<xsl:text/>or "<xsl:text/>&space;&space;&param;&space;&space;<xsl:text/>
<xsl:text/>" where normal "<xsl:text/>
<xsl:text/> &param; <xsl:text/>" or
<xsl:text/>

<xsl:text/>carriage return<xsl:text/>

<xsl:text/>
<xsl:text/>
does not work.

Using &entity; is also shorter than using 'xsl:value-of' tags.
</xsl:template>

</xsl:stylesheet>
</source>
| valign=top |
;Source file
<source lang=xml>
<?xml version="1.0"?>
<project name="myproject">
<target name="myname"/>
</project>
</source>
|}
;Processed with
:<code>xsltproc -param PARAM "'space'" -param ENTITY "'entities'" style.xsl source</code>
;output
<source lang=text>
Use entities for special characters like


carriage return


or " space " where normal "space" or
carriage return
does not work.

Using entities is also shorter than using 'xsl:value-of' tags.
</source>
|}

=== Using template parameters ===
{| class=wikitable width=100%
|-
|
{| width=100%
|-
| valign=top width=50% |
;XSLT file
<source lang=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="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project">
<xsl:text/>Calling template by matching, passing a string:
<xsl:apply-templates select="target">
<xsl:with-param name="PARAM" select="'a string'"/>
</xsl:apply-templates>
Calling template by matching, passing a GLOBALPARAM:
<xsl:apply-templates select="target">
<xsl:with-param name="PARAM" select="$GLOBALPARAM"/>
</xsl:apply-templates>
Calling template by name
<xsl:call-template name="named">
<xsl:with-param name="PARAM" select="'a string'"/>
</xsl:call-template>
</xsl:template>

<xsl:template match="target">
<xsl:param name="PARAM"/>
<xsl:text/>parameter is <xsl:value-of select="$PARAM"/><xsl:text/>
</xsl:template>

<xsl:template name="named">
<xsl:param name="PARAM"/>
<xsl:text/>parameter is <xsl:value-of select="$PARAM"/><xsl:text/>
</xsl:template>

</xsl:stylesheet>
</source>
| valign=top |
;Source file
<source lang=xml>
<?xml version="1.0"?>
<project name="myproject">
<target name="myname"/>
</project>
</source>
|}
;Processed with
:<code>xsltproc -param GLOBALPARAM "'global param'" style.xsl source</code>
;output
<source lang=text>
Calling template by matching, passing a string:
parameter is a string
Calling template by matching, passing a GLOBALPARAM:
parameter is global param
Calling template by name
parameter is a string
</source>
|}

=== Simple <code><xsl-apply-templates></code> and <code>.</code> ===
{| class=wikitable width=100%
|-
|
{| width=100%
|-
| valign=top width=50% |
;XSLT file
<source lang=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="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project">
<xsl:apply-templates select="target/*"/>
</xsl:template>

<xsl:template match="content">
<xsl:text/>dot is '<xsl:value-of select="."/>', <xsl:text/>
</xsl:template>

</xsl:stylesheet>
</source>
| valign=top |
;Source file
<source lang=xml>
<?xml version="1.0"?>
<project name="myproject">
<target name="target1">
<content>content1</content>
<content>content2</content>
<content>content3</content>
</target>
</project>
</source>
|}
;Processed with
:<code>xsltproc style.xsl source</code>
;output
<source lang=text>
dot is 'content1', dot is 'content2', dot is 'content3',
</source>
|}

=== Example of <code><xsl:for-each></code> ===
{| class=wikitable width=100%
|-
|
{| width=100%
|-
| valign=top width=50% |
;XSLT file
<source lang=xslt>
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY name '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="@name"/>'>
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project">
<xsl:text/>Simple for-each loop:
<xsl:for-each select="target/*"><xsl:text/>dot is '<xsl:value-of select="."/>', </xsl:for-each>
For-each loop with select condition:
<xsl:for-each select="target/content[@id='second']">&name;, </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
</source>
| valign=top |
;Source file
<source lang=xml>
<?xml version="1.0"?>
<project name="myproject">
<target name="target1">
<content id='first' name="only">content1</content>
<content id='second' name="double">content2</content>
<content id='third' name="last">content3</content>
</target>
</project>
</source>
|}
;Processed with
:<code>xsltproc style.xsl source</code>
;output
<source lang=text>
Simple for-each loop:
dot is 'content1', dot is 'content2', dot is 'content3',
For-each loop with select condition:
double,
</source>
|}

=== Example of <code><xsl:choose></code> ===
{| class=wikitable width=100%
|-
|
{| width=100%
|-
| valign=top width=50% |
;XSLT file
<source lang=xslt>
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY name '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="@name"/>'>
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project">
<xsl:apply-templates select="target/*"/>
</xsl:template>

<xsl:template match="target/*">
<xsl:text/><xsl:variable name="TGTTYPE">
<xsl:choose>
<xsl:when test="@type='small'">
<xsl:text/><xsl:value-of select="small"/><xsl:text/>
</xsl:when>
<xsl:otherwise>
<xsl:text/><xsl:value-of select="big"/><xsl:text/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable><xsl:text/>
<xsl:text/>We have <xsl:value-of select="$TGTTYPE"/> for <xsl:value-of select="@type"/>.
</xsl:template>


</xsl:stylesheet>
</source>
| valign=top |
;Source file
<source lang=xml>
<?xml version="1.0"?>
<project name="myproject">
<target name="target1">
<content type='small'><small>content1</small><big>CONTENT1</big></content>
<content type='big'><small>content2</small><big>CONTENT2</big></content>
<content type='small'><small>content3</small><big>CONTENT3</big></content>
</target>
</project>
</source>
|}
;Processed with
:<code>xsltproc style.xsl source</code>
;output
<source lang=text>
We have content1 for small.
We have CONTENT2 for big.
We have content3 for small.
</source>
|}

=== Template with match rule and dynamic entity ===
{| class=wikitable width=100%
|-
|
{| width=100%
|-
| valign=top width=50% |
;XSLT file
<source lang=xslt>
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY name '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="@name"/>'>
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project/target/*">
<xsl:value-of select="@type"/>
</xsl:template>


</xsl:stylesheet>
</source>
| valign=top |
;Source file
<source lang=xml>
<?xml version="1.0"?>
<project name="myproject">
<target name="target1">
<content type='small'><small>content1</small><big>CONTENT1</big></content>
<content type='big'><small>content2</small><big>CONTENT2</big></content>
<content type='small'><small>content3</small><big>CONTENT3</big></content>
</target>
</project>
</source>
|}
;Processed with
:<code>xsltproc style.xsl source</code>
;output
<source lang=text>

small
big
small
</source>
|}

=== ===
{| class=wikitable width=100%
|-
|
{| width=100%
|-
| valign=top width=50% |
;XSLT file
<source lang=xslt>
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY name '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="@name"/>'>
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project">
<xsl:apply-templates select="target/*"/>
</xsl:template>

<xsl:template match="project/target/*">
<xsl:value-of select="@type"/>
</xsl:template>


</xsl:stylesheet>
</source>
| valign=top |
;Source file
<source lang=xml>
<?xml version="1.0"?>
<project name="myproject">
<target name="target1">
<content type='small'><small>content1</small><big>CONTENT1</big></content>
<content type='big'><small>content2</small><big>CONTENT2</big></content>
<content type='small'><small>content3</small><big>CONTENT3</big></content>
</target>
</project>
</source>
|}
;Processed with
:<code>xsltproc style.xsl source</code>
;output
<source lang=text>
smallbigsmall
</source>
|}

=== Using namespace ===
{| class=wikitable width=100%
|-
|
{| width=100%
|-
| valign=top width=50% |
;XSLT file
<source lang=xslt>
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY name '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="@name"/>'>
]>

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://your.server.org/your/xsl/url/MYNS"
exclude-result-prefixes="xsl ns"
version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="ns:project">
<xsl:apply-templates select="ns:target/*"/>
</xsl:template>

<xsl:template match="ns:project/ns:target/*">
<xsl:if test="@type='small'">SMALL </xsl:if>
<xsl:if test="@type='big'">BIG </xsl:if>
</xsl:template>


</xsl:stylesheet>
</source>
| valign=top |
;Source file
<source lang=xml>
<?xml version="1.0"?>
<ns:project
xmlns:ns="http://your.server.org/your/xsl/url/MYNS"
name="myproject">
<ns:target name="target1">
<ns:content type='small'>content1</ns:content>
<ns:content type='big'>content2</ns:content>
<ns:content type='small'>content3</ns:content>
</ns:target>
</ns:project>
</source>
|}
;Processed with
:<code>xsltproc style.xsl source</code>
;output
<source lang=text>
SMALL BIG SMALL
</source>
|}

=== Example of expressions ===
{| class=wikitable width=100%
|-
|
{| width=100%
|-
| valign=top width=50% |
;XSLT file
<source lang=xslt>
<?xml version='1.0' encoding="UTF-8"?>

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:math="http://exslt.org/math"
extension-element-prefixes="math"
version='1.0'>

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

<xsl:template match="project">
<xsl:apply-templates select="target/*"/>
</xsl:template>

<xsl:template match="project/target/*">
<p>
<msg>dot is current tag content, here '.' is '<xsl:value-of select="."/>'</msg>
<msg attr="{.}">Use braces {...} in attributes</msg>
<msg random="unique.{floor(math:random()*2147483647)}">{...} can be any expression</msg>
</p>
</xsl:template>
</xsl:stylesheet>
</source>
| valign=top |
;Source file
<source lang=xml>
<?xml version="1.0"?>
<project name="myproject">
<target name="target1">
<content type='small'>content1</content>
<content type='big'>content2</content>
<content type='small'>content3</content>
</target>
</project>
</source>
|}
;Processed with
:<code>xsltproc style.xsl source</code>
;output
<source lang=text>
<?xml version="1.0" encoding="UTF-8"?>
<p>
<msg>dot is current tag content, here '.' is 'content1'</msg>
<msg attr="content1">Use braces {...} in attributes</msg>
<msg random="unique.799522789">{...} can be any expression</msg>
</p><p>
<msg>dot is current tag content, here '.' is 'content2'</msg>
<msg attr="content2">Use braces {...} in attributes</msg>
<msg random="unique.90206728">{...} can be any expression</msg>
</p><p>
<msg>dot is current tag content, here '.' is 'content3'</msg>
<msg attr="content3">Use braces {...} in attributes</msg>
<msg random="unique.2005052793">{...} can be any expression</msg>
</p>
</source>
|}

=== Generate custom XML tags ===
{| class=wikitable width=100%
|-
|
{| width=100%
|-
| valign=top width=50% |
;XSLT file
<source lang=xslt>
<?xml version='1.0' encoding="UTF-8"?>

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:math="http://exslt.org/math"
extension-element-prefixes="math"
version='1.0'>

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

<xsl:template match="project">
<xsl:text disable-output-escaping="yes">&lt;?fileVersion 4.0.0?&gt;</xsl:text><cproject id="my project"/>
<p>Use 'disable-output-escaping' to generate xml tags.</p>
</xsl:template>
</xsl:stylesheet>
</source>
| valign=top |
;Source file
<source lang=xml>
<?xml version="1.0"?>
<project name="myproject">
<target name="target1">
<content type='small'>content1</content>
<content type='big'>content2</content>
<content type='small'>content3</content>
</target>
</project>
</source>
|}
;Processed with
:<code>xsltproc style.xsl source</code>
;output
<source lang=text>
<?xml version="1.0" encoding="UTF-8"?>
<?fileVersion 4.0.0?><cproject id="my project"/><p>Use 'disable-output-escaping' to generate xml tags.</p>
</source>
|}

=== Removing white spaces ===
{| class=wikitable width=100%
|-
|
{| width=100%
|-
| valign=top width=50% |
;XSLT file
<source lang=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" version="1.0" encoding="UTF-8" standalone="no"/>

<xsl:template match="project">
<project>
<xsl:apply-templates select="*"/>
</project>
</xsl:template>

<xsl:template match="target">
<cleaned_target><xsl:value-of select="normalize-space(.)"/></cleaned_target>
</xsl:template>
</xsl:stylesheet>
</source>
| valign=top |
;Source file
<source lang=xml>
<?xml version="1.0"?>
<project name="myproject">
<target>no_space_at_all</target>
<target> with_space_around </target>
<target>with
carriage
returns
</target>
<target>with spaces between the words</target>
</project>
</source>
|}
;Processed with
:<code>xsltproc style.xsl source</code>
;output
<source lang=text>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<cleaned_target>no_space_at_all</cleaned_target>
<cleaned_target>with_space_around</cleaned_target>
<cleaned_target>with carriage returns</cleaned_target>
<cleaned_target>with spaces between the words</cleaned_target>
</project>
</source>
|}


== Miscellaneous ==
== Miscellaneous ==

Revision as of 18:17, 13 December 2016

XSLT stands for Extensible Stylesheet Language Transformations.

Links

Gnome library
exslt (extensions)
Extensions supported in libxml (xsltproc processor)

Overview

Currently there are two versions of the XSLT standards: XSLT 1.0 and XSLT 2.0.

XSLT 1.0
On linux, the standard XSLT 1.0 processor is xsltproc (from package xsltproc, libxml2 library).
In XSLT 1.0, most functions come from XSLT extensions (like http://exslt.org/).


XSLT 2.0
  • On linux, the standard XSLT 2.0 processor is saxonb-xslt (from package libsaxonb-java).
  • XSLT 2.0 introduces XQuery, XPath 2.0, and XSLT functions (with prefix fn:). See here for a detailed list of features.

Extensions

From w3.org [1]:

  • The element extension mechanism allows namespaces to be designated as extension namespaces. When a namespace is designated as an extension namespace and an element with a name from that namespace occurs in a template, then the element is treated as an instruction rather than as a literal result element.

Extensions available in the XSLT processor

Using xsltproc (package xsltproc [2], we can get the list of built-in extensions with:

xsltproc --dumpextensions 
# Registered XSLT Extensions
# --------------------------
# Registered Extension Functions:
# {http://exslt.org/math}atan2
# {http://exslt.org/strings}align
# ...
exslt.org/crypto
  • "Hidden" extensions that provides basic crypto functions (apparently from patch [3], introduced in July 5 2004 [4])
  • See also [5]
  • CAUTION — These extensions are not available if using a custom implementation of Python like Anaconda
xsltproc --dumpextensions|grep crypto
# {http://exslt.org/crypto}rc4_decrypt
# {http://exslt.org/crypto}md4
# {http://exslt.org/crypto}sha1
# {http://exslt.org/crypto}md5
# {http://exslt.org/crypto}rc4_encrypt
Example of use:
<xsl:template match="rootnode">
<xsl:value-of select="crypto:md5('ahahah')"/>
</xsl:template>

Quick reference

xsl:attribute

Input Output
<link site="www.stackoverflow.com"/>
<a href="http://www.stackoverflow.com">Click here</a>

Use

<xsl:template match="link">
    <a>
        <xsl:attribute name="href">
            <xsl:text>http://</xsl:text><xsl:value-of select="@site"/>
        </xsl:attribute>
        <xsl:text>Link</xsl:text>
    </a>
</xsl:template>

Or shorter using curly braces {...} [6]:

<xsl:template match="link">
    <a href="http://{@site}">Click here</a>
</xsl:template>

Also for:

Tips

Output tags like <?fileVersion 4.0.0 ?>

Use a xsl:text tag with attribute disable-output-escaping="yes": [7]:

<xsl:template match="/">
<xsl:text disable-output-escaping="yes">&lt;?fileVersion 4.0.0?&gt;</xsl:text>
</xsl:template>

This will produce:

<?fileVersion 4.0.0?>

Generate a random UID

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:data="http://exslt.org/dates-and-times"
    xmlns:math="http://exslt.org/math"
    extension-element-prefixes="date math"
    version='1.0'>
<!-- .... -->
<xsl:variable name="noncels" select="floor(math:random()*800)+100"/>
<xsl:variable name="noncems" select="data:seconds(date:date-time())-date:seconds('1970-01-01T00:00:00')"/>
<!-- .... -->
<xsl:value-of select="concat($noncems,noncels+0)"/>
</xsl:stylesheet>

Examples

Simple <xsl:template>

XSLT file
<?xml version='1.0' encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:param name="PARAM"/>

<xsl:template match="project">
<xsl:text/>This template will replace 'project' by a simple <xsl:value-of select="$PARAM"/><xsl:text/>
</xsl:template>

</xsl:stylesheet>
Source file
<?xml version="1.0"?>
<project name="myproject">
        <target name="myname"/>
</project>
Processed with
xsltproc -param PARAM "'text'" style.xsl source
output
This template will replace 'project' by a simple text

Spaces and CR

XSLT file
<?xml version='1.0' encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:param name="WORLD"/>

<xsl:template match="project">
    <xsl:text>CR/spaces are preserved...
    inside 'xsl:text'.</xsl:text>

<xsl:text> But spaces/CR between two tags are deleted.</xsl:text>
Except if ...
    it contains non-blanks.
    <xsl:text/>So better use empty text tags<xsl:text/>
    <xsl:text/> to eat spaces/CR, while still using
    ... xslt <xsl:value-of select="$PARAM"/><xsl:text/>
</xsl:template>

</xsl:stylesheet>
Source file
<?xml version="1.0"?>
<project name="myproject">
    <target name="myname"/>
</project>
Processed with
xsltproc -param PARAM "'parameters.'" style.xsl source
output
CR/spaces are preserved...
    inside 'xsl:text'. But spaces/CR between two tags are deleted.
Except if ...
    it contains non-blanks.
    So better use empty text tags to eat spaces/CR, while still using
    ... xslt parameters.

Using entities

XSLT file
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY cr '<xsl:text xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
</xsl:text>'>
<!ENTITY space '<xsl:text xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> </xsl:text>'>
<!ENTITY param '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="$PARAM"/>'>
<!ENTITY entity '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="$ENTITY"/>'>
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project">
<xsl:text/>Use entities for special characters like<xsl:text/>
<xsl:text/>&cr;&cr;<xsl:text/>
    carriage return
<xsl:text/>&cr;&cr;<xsl:text/>
<xsl:text/>or "<xsl:text/>&space;&space;&param;&space;&space;<xsl:text/>
<xsl:text/>" where normal "<xsl:text/>
<xsl:text/>  &param;  <xsl:text/>" or
<xsl:text/>

<xsl:text/>carriage return<xsl:text/>

<xsl:text/>
<xsl:text/>
does not work.

Using &entity; is also shorter than using 'xsl:value-of' tags.
</xsl:template>

</xsl:stylesheet>
Source file
<?xml version="1.0"?>
<project name="myproject">
    <target name="myname"/>
</project>
Processed with
xsltproc -param PARAM "'space'" -param ENTITY "'entities'" style.xsl source
output
Use entities for special characters like


    carriage return


or "  space  " where normal "space" or
carriage return
does not work.

Using entities is also shorter than using 'xsl:value-of' tags.

Using template parameters

XSLT file
<?xml version='1.0' encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project">
<xsl:text/>Calling template by matching, passing a string:
<xsl:apply-templates select="target">
	<xsl:with-param name="PARAM" select="'a string'"/>
</xsl:apply-templates>
Calling template by matching, passing a GLOBALPARAM:
<xsl:apply-templates select="target">
	<xsl:with-param name="PARAM" select="$GLOBALPARAM"/>
</xsl:apply-templates>
Calling template by name
<xsl:call-template name="named">
    <xsl:with-param name="PARAM" select="'a string'"/>
</xsl:call-template>
</xsl:template>

<xsl:template match="target">
    <xsl:param name="PARAM"/>
    <xsl:text/>parameter is <xsl:value-of select="$PARAM"/><xsl:text/>
</xsl:template>

<xsl:template name="named">
    <xsl:param name="PARAM"/>
    <xsl:text/>parameter is <xsl:value-of select="$PARAM"/><xsl:text/>
</xsl:template>

</xsl:stylesheet>
Source file
<?xml version="1.0"?>
<project name="myproject">
    <target name="myname"/>
</project>
Processed with
xsltproc -param GLOBALPARAM "'global param'" style.xsl source
output
Calling template by matching, passing a string:
parameter is a string
Calling template by matching, passing a GLOBALPARAM:
parameter is global param
Calling template by name
parameter is a string

Simple <xsl-apply-templates> and .

XSLT file
<?xml version='1.0' encoding="UTF-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project">
<xsl:apply-templates select="target/*"/>
</xsl:template>

<xsl:template match="content">
    <xsl:text/>dot is '<xsl:value-of select="."/>', <xsl:text/>
</xsl:template>

</xsl:stylesheet>
Source file
<?xml version="1.0"?>
<project name="myproject">
    <target name="target1">
        <content>content1</content>
        <content>content2</content>
        <content>content3</content>
    </target>
</project>
Processed with
xsltproc style.xsl source
output
dot is 'content1', dot is 'content2', dot is 'content3',

Example of <xsl:for-each>

XSLT file
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY name '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="@name"/>'>
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project">
<xsl:text/>Simple for-each loop:
    <xsl:for-each select="target/*"><xsl:text/>dot is '<xsl:value-of select="."/>', </xsl:for-each>
For-each loop with select condition:
    <xsl:for-each select="target/content[@id='second']">&name;, </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
Source file
<?xml version="1.0"?>
<project name="myproject">
    <target name="target1">
        <content id='first' name="only">content1</content>
        <content id='second' name="double">content2</content>
        <content id='third' name="last">content3</content>
    </target>
</project>
Processed with
xsltproc style.xsl source
output
Simple for-each loop:
    dot is 'content1', dot is 'content2', dot is 'content3', 
For-each loop with select condition:
    double,

Example of <xsl:choose>

XSLT file
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY name '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="@name"/>'>
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project">
<xsl:apply-templates select="target/*"/>
</xsl:template>

<xsl:template match="target/*">
<xsl:text/><xsl:variable name="TGTTYPE">
    <xsl:choose>
        <xsl:when test="@type='small'">
            <xsl:text/><xsl:value-of select="small"/><xsl:text/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:text/><xsl:value-of select="big"/><xsl:text/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:variable><xsl:text/>
<xsl:text/>We have <xsl:value-of select="$TGTTYPE"/> for <xsl:value-of select="@type"/>.
</xsl:template>


</xsl:stylesheet>
Source file
<?xml version="1.0"?>
<project name="myproject">
    <target name="target1">
        <content type='small'><small>content1</small><big>CONTENT1</big></content>
        <content type='big'><small>content2</small><big>CONTENT2</big></content>
        <content type='small'><small>content3</small><big>CONTENT3</big></content>
    </target>
</project>
Processed with
xsltproc style.xsl source
output
We have content1 for small.
We have CONTENT2 for big.
We have content3 for small.

Template with match rule and dynamic entity

XSLT file
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY name '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="@name"/>'>
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project/target/*">
    <xsl:value-of select="@type"/>
</xsl:template>


</xsl:stylesheet>
Source file
<?xml version="1.0"?>
<project name="myproject">
    <target name="target1">
        <content type='small'><small>content1</small><big>CONTENT1</big></content>
        <content type='big'><small>content2</small><big>CONTENT2</big></content>
        <content type='small'><small>content3</small><big>CONTENT3</big></content>
    </target>
</project>
Processed with
xsltproc style.xsl source
output
    
        small
        big
        small

XSLT file
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY name '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="@name"/>'>
]>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="project">
    <xsl:apply-templates select="target/*"/>
</xsl:template>

<xsl:template match="project/target/*">
    <xsl:value-of select="@type"/>
</xsl:template>


</xsl:stylesheet>
Source file
<?xml version="1.0"?>
<project name="myproject">
    <target name="target1">
        <content type='small'><small>content1</small><big>CONTENT1</big></content>
        <content type='big'><small>content2</small><big>CONTENT2</big></content>
        <content type='small'><small>content3</small><big>CONTENT3</big></content>
    </target>
</project>
Processed with
xsltproc style.xsl source
output
smallbigsmall

Using namespace

XSLT file
<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY name '<xsl:value-of xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="@name"/>'>
]>

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ns="http://your.server.org/your/xsl/url/MYNS" 
    exclude-result-prefixes="xsl ns"
    version='1.0'>

<xsl:output method="text" indent="no" encoding="UTF-8"/>

<xsl:template match="ns:project">
    <xsl:apply-templates select="ns:target/*"/>
</xsl:template>

<xsl:template match="ns:project/ns:target/*">
    <xsl:if test="@type='small'">SMALL </xsl:if>
    <xsl:if test="@type='big'">BIG </xsl:if>
</xsl:template>


</xsl:stylesheet>
Source file
<?xml version="1.0"?>
<ns:project 
    xmlns:ns="http://your.server.org/your/xsl/url/MYNS" 
    name="myproject">
    <ns:target name="target1">
        <ns:content type='small'>content1</ns:content>
        <ns:content type='big'>content2</ns:content>
        <ns:content type='small'>content3</ns:content>
    </ns:target>
</ns:project>
Processed with
xsltproc style.xsl source
output
SMALL BIG SMALL

Example of expressions

XSLT file
<?xml version='1.0' encoding="UTF-8"?>

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:math="http://exslt.org/math"
    extension-element-prefixes="math"
    version='1.0'>

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

    <xsl:template match="project">
        <xsl:apply-templates select="target/*"/>
    </xsl:template>

    <xsl:template match="project/target/*">
        <p>
            <msg>dot is current tag content, here '.' is '<xsl:value-of select="."/>'</msg>
            <msg attr="{.}">Use braces {...} in attributes</msg>
            <msg random="unique.{floor(math:random()*2147483647)}">{...} can be any expression</msg>
        </p>
    </xsl:template>
</xsl:stylesheet>
Source file
<?xml version="1.0"?>
<project name="myproject">
    <target name="target1">
        <content type='small'>content1</content>
        <content type='big'>content2</content>
        <content type='small'>content3</content>
    </target>
</project>
Processed with
xsltproc style.xsl source
output
<?xml version="1.0" encoding="UTF-8"?>
<p>
  <msg>dot is current tag content, here '.' is 'content1'</msg>
  <msg attr="content1">Use braces {...} in attributes</msg>
  <msg random="unique.799522789">{...} can be any expression</msg>
</p><p>
  <msg>dot is current tag content, here '.' is 'content2'</msg>
  <msg attr="content2">Use braces {...} in attributes</msg>
  <msg random="unique.90206728">{...} can be any expression</msg>
</p><p>
  <msg>dot is current tag content, here '.' is 'content3'</msg>
  <msg attr="content3">Use braces {...} in attributes</msg>
  <msg random="unique.2005052793">{...} can be any expression</msg>
</p>

Generate custom XML tags

XSLT file
<?xml version='1.0' encoding="UTF-8"?>

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:math="http://exslt.org/math"
    extension-element-prefixes="math"
    version='1.0'>

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

    <xsl:template match="project">
        <xsl:text disable-output-escaping="yes">&lt;?fileVersion 4.0.0?&gt;</xsl:text><cproject id="my project"/>
        <p>Use 'disable-output-escaping' to generate xml tags.</p>
    </xsl:template>
</xsl:stylesheet>
Source file
<?xml version="1.0"?>
<project name="myproject">
    <target name="target1">
        <content type='small'>content1</content>
        <content type='big'>content2</content>
        <content type='small'>content3</content>
    </target>
</project>
Processed with
xsltproc style.xsl source
output
<?xml version="1.0" encoding="UTF-8"?>
<?fileVersion 4.0.0?><cproject id="my project"/><p>Use 'disable-output-escaping' to generate xml tags.</p>

Removing white spaces

XSLT file
<?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" version="1.0" encoding="UTF-8" standalone="no"/>

    <xsl:template match="project">
        <project>
            <xsl:apply-templates select="*"/>
        </project>
    </xsl:template>

    <xsl:template match="target">
        <cleaned_target><xsl:value-of select="normalize-space(.)"/></cleaned_target>
    </xsl:template>
</xsl:stylesheet>
Source file
<?xml version="1.0"?>
<project name="myproject">
    <target>no_space_at_all</target>
    <target>   with_space_around  </target>
    <target>with
        carriage
        returns
    </target>
    <target>with  spaces  between  the  words</target>
</project>
Processed with
xsltproc style.xsl source
output
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
  <cleaned_target>no_space_at_all</cleaned_target>
  <cleaned_target>with_space_around</cleaned_target>
  <cleaned_target>with carriage returns</cleaned_target>
  <cleaned_target>with spaces between the words</cleaned_target>
</project>

Miscellaneous

  • <xsl:param name="MYPARAM"> in <xsl:stylesheet> node declares a global parameter.
After this declaration we can use $MYPARAM to get the value of the parameter. If it is not declared, we can only use $MYPARAM if it is passed as a parameter (e.g. via command line xsltproc -param MYPARAM "'myparamvalu'"), otherwise an error is triggered.