XSLT для сортировки узлов по имени?

Я не знаю, как работает директива xsl:sort. Мне нужно отсортировать элементы по их имени тега (для разных), и я не могу придумать, как это сделать. Моим первым было изменить модификацию идентичности и просто изменить ее, чтобы включить оператор сортировки, но я не совсем уверен, как это сделать.

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

Ответ 1

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

<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:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="@*">
    <xsl:sort select="name()"/>
   </xsl:apply-templates>

   <xsl:apply-templates select="node()">
    <xsl:sort select="name()"/>
   </xsl:apply-templates>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

при применении к этому XML-документу:

<t b="x" c="y" a="t">
  <c/>
  <b/>
  <a/>
</t>

создает желаемый отсортированный вывод:

<t a="t" b="x" c="y">
    <a></a>
    <b></b>
    <c></c>
</t>

Обратите внимание:

  • Не только элементы, но и атрибуты отсортированы (последний зависит от реализации, но работает нормально с MSXML).

  • Использование отсортированного XML для diffs является ненадежным, поскольку преобразование XML-документа в отсортированное представление не является отображением 1:1.