Сортировка XML в XSLT на основе списка значений - PullRequest
5 голосов
/ 24 января 2011

Я бы хотел отсортировать один XML-файл с XSL-преобразованием.

<root>
   <element>
        <name>A</name>
   </element>
   <element>
        <name>B</name>
   </element>
   <element>
        <name>C</name>
   </element>
</root>

Должен быть отсортирован по следующему списку имен: C, A, B, чтобы результирующий XML был:

 <root>
       <element>
            <name>C</name>
       </element>
       <element>
            <name>A</name>
       </element>
       <element>
            <name>B</name>
       </element>
    </root>

Очевидно, что список значений для сортировки должен быть довольно динамичным (параметр XSLT, другой файл XML ...).Есть идеи, как это сделать в XSLT?

Спасибо, Кристоф

1 Ответ

9 голосов
/ 24 января 2011

Это преобразование :

<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="pSortingValues" select="'C,A,B'"/>
 <xsl:variable name="vSortingValues" select=
  "concat(',', $pSortingValues, ',')"/>

    <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="/*">
      <xsl:copy>
       <xsl:apply-templates select="@*"/>
       <xsl:apply-templates select="*">
        <xsl:sort data-type="number" select=
        "string-length(substring-before($vSortingValues,concat(',',name,',')))"/>
       </xsl:apply-templates>
      </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<root>
    <element>
        <name>A</name>
    </element>
    <element>
        <name>B</name>
    </element>
    <element>
        <name>C</name>
    </element>
</root>

дает желаемые, правильные результаты :

<root>
   <element>
      <name>C</name>
   </element>
   <element>
      <name>A</name>
   </element>
   <element>
      <name>B</name>
   </element>
</root>

Примечание :

  1. Список требуемых отсортированных значений - это глобальный параметр pSortingValues , который может быть предоставлен для преобразования извне.

  2. Правило идентификации используется для копирования всех узлов "как есть".

  3. Правило идентификации переопределяется для верхнего элемента . Верхний элемент частично копируется, его атрибуты копируются, затем шаблоны применяются ко всем дочерним элементам с помощью дочерней инструкции <xsl:sort>, которая указывает точный используемый ключ сортировки - как перед значениями pSortingValues имя ребенка element.

ОБНОВЛЕНИЕ : Как отмечает @Alejandro, это:

        <xsl:sort data-type="number" select=
        "string-length(substring-before($vSortingValues,concat(',',name,',')))"/>

можно упростить до этого:

        <xsl:sort data-type="number" select=
        "substring-before($vSortingValues,concat(',',name,','))"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...