<name>John</name>
<surname>Fowles</surname>
</person>
</list>
Отсортируем этот список сначала по именам в убывающем, а затем по фамилиям в возрастающем порядке.
<xsl:template match='list'>
<xsl:copy>
<xsl:for-each select='person'>
<xsl:sort select='name' order='descending'/>
<xsl:sort select='surname'/>
<xsl:copy-of select='.'/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<list>
<person>
<name>William</name>
<surname>Blake</surname>
</person>
<person>
<name>William</name>
<surname>Gibson</surname>
</person>
<person>
<name>John</name>
<surname>Fowles</surname>
</person>
</list>
К сожалению, сортировкой нельзя управлять динамически. Все атрибуты элемента xsl:sort
должны обладать фиксированными значениями.
Псевдонимы пространств имен
Любопытным фактом является то, что XML-документ, являющийся результатом выполнения XSLT- преобразования, может и сам быть XSLT- преобразованием. Иными словами, преобразования могут генерироваться другими преобразованиями. В некоторых случаях такая возможность будет очень полезна, например, входящий XML-документ может описывать преобразование, которое нужно сгенерировать.
<transform>
<remove select='a'/>
<replace select='b' with='B'/>
<replace select='c' with='C'/>
</transform>
Приведенный выше документ описывает преобразование, которое должно удалять из входящего документа элементы а
, а элементы b
и c
заменять элементами B
и C
соответственно. Такое преобразование может выглядеть следующим образом.
<xsl:stylesheet
version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:template match='a'/>
<xsl:template match='b'>
<xsl:element name='B'>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match='c'>
<xsl:element name='C'>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match='@*|node()'>
<xsl:copy>
<xsl:apply-templates select='@*|node()'/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Преобразование, генерирующее такой код, не представляет особой сложности. Например, шаблон для обработки элемента replace может иметь следующий вид:
<xsl:template match='replace'>
<xsl:element name='xsl:template'>
<xsl:attribute name='match'>
<xsl:value-of select='@select'/>
</xsl:attribute>
<xsl:element name='xsl:element'>
<xsl:attribute name='name'>
<xsl:value-of select='@with'/>
</xsl:attribute>
<xsl:element name='xsl:apply-templates'/>
</xsl:element>
</xsl:element>
</xsl:template>
Шаблон этот выглядит очень громоздко, потому что мы не могли просто включить в него создаваемое правило: поскольку мы создаем элементы в пространстве имен XSLT, находясь в шаблоне, они воспринимались бы не как генерируемые, а как принадлежащие генерирующему преобразованию. Очевидно, что шаблон вида
<xsl:template match='replace'>