Использование XSL для сортировки атрибутов

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

Я был удивлен тем, что не нашел XSL-пример того, как это сделать. В основном я хочу только преобразование идентичности с отсортированными атрибутами. Я придумал следующее, похоже, работает во всех моих тестовых случаях:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
  <xsl:template match="*|/|text()|comment()|processing-instruction()">
    <xsl:copy>
    <xsl:for-each select="@*">
        <xsl:sort select="name(.)"/>
        <xsl:copy/>
      </xsl:for-each>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Как полный XSL n00b, я был бы признателен за любые комментарии по стилю или эффективности. Я подумал, что было бы полезно опубликовать его здесь, так как это, по крайней мере, не общий пример.

Ответ 1

С xslt, являющимся функциональным языком, использующим for-each, часто может быть самый простой путь для нас, но не самый эффективный для XSLT-процессоров, поскольку они не могут полностью оптимизировать вызов.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
  <xsl:template match="*">
    <xsl:copy>
      <xsl:apply-templates select="@*">
        <xsl:sort select="name()"/>
      </xsl:apply-templates>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="@*|comment()|processing-instruction()">
    <xsl:copy />     
  </xsl:template>
</xsl:stylesheet>

Это совершенно тривиально в этом отношении, хотя и как "XSL n00b", я думаю, что вы решили проблему очень хорошо.

Ответ 2

Хорошо сделано для решения проблемы. Поскольку я предполагаю, что вы знаете, что порядок или атрибуты несущественны для синтаксических анализаторов XML, поэтому основное преимущество этого упражнения для людей - машина будет переупорядочивать их на вводе или выходе непредсказуемым образом.

Канонизация в XML не является тривиальной, и вам было бы полезно использовать канонизатор, снабженный любым разумным инструментарием XML, а не писать свои собственные.