В общем случае невозможно выполнить динамическую оценку выражений XPath - ни в XSLT / Xpath 1.0, ни в XSLT / Xpath 2.0 .
При этом всегда можно реализовать сортировку по переменным, если есть ограничения на их содержимое.
Вот пример, который решает вашу конкретную проблему и класс подобных проблем:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pSortName" select="'authors'"/>
<xsl:param name="pSortPosition" select="1"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="records">
<records>
<xsl:apply-templates>
<xsl:sort select=
".//*[name()=$pSortName]/*
[position()=$pSortPosition]"/>
</xsl:apply-templates>
</records>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется к этому документу XML :
<records>
<record>
<contributors>
<authors>
<author>X.Y.Z</author>
<author>A.B.C</author>
</authors>
</contributors>
<titles>
<title>Title B</title>
<secondary-title>Title AB</secondary-title>
</titles>
<dates>
<year>1901</year>
</dates>
</record>
<record>
<contributors>
<authors>
<author>T.U.V</author>
<author>D.E.F</author>
</authors>
</contributors>
<titles>
<title>Title A</title>
<secondary-title>Title BA</secondary-title>
</titles>
<dates>
<year>2001</year>
</dates>
</record>
</records>
желаемый, правильный результат (записи отсортированы по первому автору) :
<records>
<record>
<contributors>
<authors>
<author>T.U.V</author>
<author>D.E.F</author>
</authors>
</contributors>
<titles>
<title>Title A</title>
<secondary-title>Title BA</secondary-title>
</titles>
<dates>
<year>2001</year>
</dates>
</record>
<record>
<contributors>
<authors>
<author>X.Y.Z</author>
<author>A.B.C</author>
</authors>
</contributors>
<titles>
<title>Title B</title>
<secondary-title>Title AB</secondary-title>
</titles>
<dates>
<year>1901</year>
</dates>
</record>
</records>
Если мы изменим параметры на :
<xsl:param name="pSortName" select="'authors'"/>
<xsl:param name="pSortPosition" select="2"/>
, затем преобразование сортируется с использованием в качестве ключа сортировки второго author
.
Если мы изменим параметры на :
<xsl:param name="pSortName" select="'titles'"/>
<xsl:param name="pSortPosition" select="1"/>
, затем преобразование сортируется с использованием в качестве ключа сортировки элемента titles/title
.
Если мы изменим параметры на :
<xsl:param name="pSortName" select="'titles'"/>
<xsl:param name="pSortPosition" select="2"/>
, затем преобразование сортируется с использованием в качестве ключа сортировки элемента titles/secondary-title
.
Do note : Здесь мы предполагаем, что будет существовать уникальный потомок любого сортируемого элемента, имя которого равно значению, указанному в pSortName
. Мы также предполагаем, что этот элемент имеет дочерние элементы, а pSortPosition
указывает позицию дочернего элемента, который будет использоваться в качестве ключа сортировки.