<xsl:perform-sort> XSLT

Become a Patron!

Элемент xsl:perform-sort сортирует последовательность. Сортируемая последовательность определяется атрибутом select либо строится внутри самого элемента <xsl:perform-sort>.

Элементы-потомки:

Синтаксис

XSLT 2.0 и XSLT 3.0

<xsl:perform-sort
    select? = expression>
    <!-- Content: (xsl:sort+, sequence-constructor) -->
</xsl:perform-sort>

Атрибуты

  • selectнеобязательный атрибут, выражение XPath, определяющее сортируемые объекты. При наличии атрибута select элемент <xsl:perform-sort> может содержать только элементы <xsl:sort> и <xsl:fallback>. Иначе говоря, с атрибутом select элементу <xsl:perform-sort> не разрешается строить последовательность, потому что она уже задана атрибутом select.

Содержимое

Элемент <xsl:perform-sort> содержит один или несколько элементов <xsl:sort>, а также произвольное количество элементов <xsl:fallback>. Если атрибут select не определен, <xsl:perform-sort> может содержать конструктор последовательности. Если атрибут select отсутствует, а элемент <xsl:perform-sort> не создает последовательность, то результатом является пустая последовательность.

Описание и примеры

Пример

Начнем с элемента <xsl:perform-sort>, использующего атрибут select для создания отсортированной последовательности. Таблица стилей:

<?xml version="1.0"?>
<!-- perform-sort4.xsl -->
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="text"/>
    <xsl:variable name="vendorsInOrder" as="xs:string*">
        <xsl:perform-sort select="/report/brand/name">
            <xsl:sort select="."/>
        </xsl:perform-sort>
    </xsl:variable>
    <xsl:template match="/">
        <xsl:text>We sell these brands of chocolate:</xsl:text>
        <xsl:value-of select="$vendorsInOrder" separator=""/>
    </xsl:template>
</xsl:stylesheet>

Таблица стилей обрабатывает документ с данными о продажах шоколада:

<?xml version="1.0" encoding="utf-8"?>
<!-- chocolate.xml -->
<report month="8" year="2006">
    <title>Chocolate bar sales</title>
    <brand>
        <name>Lindt</name>
        <units>27408</units>
    </brand>
    <brand>
        <name>Callebaut</name>
        <units>8203</units>
    </brand>
    <brand>
        <name>Valrhona</name>
        <units>22101</units>
    </brand>
    <brand>
        <name>Perugina</name>
        <units>14336</units>
    </brand>
    <brand>
        <name>Ghirardelli</name>
        <units>19268</units>
    </brand>
</report>

Результат:

We sell these brands of chocolate:
Callebaut
Ghirardelli
Lindt
Perugina
Valrhona

Атрибут select элемента <xsl:perform-sort> создает последовательность всех элементов <name> в исходном документе. Имена элементов сортируются и возвращаются в виде последовательности, которая сохраняется в переменной vendorsInOrder. Учтите, что <xsl:perform-sort> возвращает последовательность из нуля, одного или нескольких объектов.

Элементы <xsl:sort> могут иметь произвольную сложность. В нашем примере создаваемая последовательность базируется на названиях брендов, но порядок сортировки определяется объемами продаж:

<?xml version="1.0"?>
<!-- perform-sort5.xsl -->
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="text"/>
    <xsl:variable name="vendorsInOrder" as="xs:string*">
        <xsl:perform-sort select="/report/brand/name">
            <xsl:sort select="../units" data-type="number" order="descending"/>
        </xsl:perform-sort>
    </xsl:variable>
    <xsl:template match="/">
        <xsl:text>Here are our best-selling brands:</xsl:text>
        <xsl:value-of select="$vendorsInOrder" separator=""/>
    </xsl:template>
</xsl:stylesheet>

Теперь результат выглядит иначе:

Here are our best-selling brands:
Lindt
Valrhona
Ghirardelli
Perugina
Callebaut

Для определения объектов последовательности по-прежнему используется атрибут select, но сортировка осуществляется по более сложному ключу. Чтобы привести пример элемента <xsl:perform-sort>, не использующего атрибут select, мы воспользуемся элементом <xsl:sequence> для выбора узлов:

<?xml version="1.0"?>
<!-- perform-sort6.xsl -->
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="text"/>
    <xsl:variable name="vendorsInOrder" as="xs:string*">
        <xsl:perform-sort>
            <xsl:sort select="../units" data-type="number" order="descending"/>
            <xsl:sequence select="/report/brand/name"/>
        </xsl:perform-sort>
    </xsl:variable>
    <xsl:template match="/">
        <xsl:text>Here are our best-selling brands:</xsl:text>
        <xsl:value-of select="$vendorsInOrder" separator=""/>
    </xsl:template>
</xsl:stylesheet>

Мы получаем прежний результат, но с более странным синтаксисом. В элементе <xsl:perform-sort> на первом месте должны размещаться элементы <xsl:sort> (один или несколько). Они определяют ключ сортировки для последовательности объектов, создаваемой в самом элементе <xsl:perform-sort>. При желании можно сгенерировать и более сложную последовательность:

<?xml version="1.0"?>
<!-- perform-sort7.xsl -->
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="text"/>
    <xsl:variable name="vendorsInOrder" as="xs:string*">
        <xsl:perform-sort>
            <xsl:sort select="." data-type="number" order="descending"/>
            <xsl:sequence select="/report/brand/units"/>
            <xsl:sequence select="('3829', '28852', '18831')"/>
        </xsl:perform-sort>
    </xsl:variable>
    <xsl:template match="/">
        <xsl:text>Here are our sales figures:</xsl:text>
        <xsl:value-of select="$vendorsInOrder" separator=""/>
    </xsl:template>
</xsl:stylesheet>

В таблицу включены фиктивные данные о продажах. Результат показывает, что дополнительные значения были включены в последовательность до сортировки:

Here are our sales figures:
28852
27408
22101
19268
18831
14336
8203
3829

Данные сортируются по убыванию, потому что в элемент <xsl:sort> включен атрибут order="descending".