Использование XSL для сортировки атрибутов - PullRequest
10 голосов
/ 16 сентября 2009

Я пытаюсь канонизировать представление некоторых данных 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 я буду признателен за любые комментарии по стилю или эффективности. Я подумал, что было бы полезно опубликовать это здесь, так как это, по крайней мере, не обычный пример.

Ответы [ 2 ]

11 голосов
/ 16 сентября 2009

Поскольку xslt является функциональным языком, выполнение для каждого из них часто является самым простым путем для нас, людей, но не самым эффективным для процессоров 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 голосов
/ 16 сентября 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...