Линукс, Vim, LaTeX, полезные скрипты, визуализация данных, численные расчёты, немного ФП

20090820

Автоматические отступы в XML

Для просмотра какого-нибудь XML часто нужно автоматически его отформатировать (чтобы отступы слева соответствовали вложенности элементов). Особенно это полезно, когда весь исходный XML записан в одну большую строку. Такие файлы — это нечитаемая каша, которую, однако, легко привести в порядок.

Первый способ — используем XSLT
Есть у меня файл с вот таким XSL-преобразованием:
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:param name="indent-increment" select="' '" />

<xsl:template match="*">
<xsl:param name="indent" select="'&#xA;'"/>

<xsl:value-of select="$indent"/>
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates>
<xsl:with-param name="indent"
select="concat($indent, $indent-increment)"/>
</xsl:apply-templates>
<xsl:value-of select="$indent"/>
</xsl:copy>
</xsl:template>

<xsl:template match="comment()|processing-instruction()">
<xsl:copy />
</xsl:template>

<!-- WARNING: this is dangerous. Handle with care -->
<xsl:template match="text()[normalize-space(.)='']"/>

</xsl:stylesheet>

Код взял здесь (предложил Николай Григорьев). Там ещё несколько вариантов есть.

В дополнение к XSL-файлу есть у меня ещё и скрипт-однострочник, который это преобразование применяет. Я выполняю XSL с помощью любимого мной xmlstarlet. Это программка с интерфейсом командной строки для работы с XML.
#!/bin/sh
# указать правильный путь к файлу с преобразованием!
xmlstarlet tr ~/bin/indent-xml.xsl

Пользуюсь этим скриптом так:
$ xmlindent < исходный.xml | view -

И всё, можно читать любой XML с правильными отступами. И подсветкой синтаксиса (view — это Vim!). Кроме xmlstarlet есть и другие XSLT-процессоры. На память приходит xsltproc и библиотечки для разных языков программирования. Вот, например, однострочник на Python.

Второй способ — используем xmllint
В пакете libxml2-utils есть программка для проверки и форматирования XML — xmllint. Для форматирования использовать так:
$ xmllint --format исходный.xml

Так даже проще.

Третий способ — xmlindent
xmlindent — отдельная утилита, написанная на чистом Си. Говорят, работает и с задачей справляется.

По теме:
Редактирование HTML и XML в Vim (добавил про HTML Entities)
Выделение HTML-тегов, строк и блоков кода в Vim
Vim в терминале: сохранение отступов вставленного текста

7 коммент.:

  1. Ой как сложно. Проще сделать:
    xmllint file.xml --format

    ОтветитьУдалить
  2. Благодарю! Про xmllint --format не знал. Пригодится. Заметку обновлю.

    ОтветитьУдалить
  3. На что тока люди не готовы, чтобы Tidy не осваивать ;-)

    ОтветитьУдалить
  4. Существует также отличная небольшая утилита на чистом C специально для форматирования XML: xmlindent.

    ОтветитьУдалить
  5. 2 kisa-i-osya

    Tidy, насколько я помню, только для XHTML. Задача — приведение к читаемому виду XML вообще (куча разных форматов данных).

    2 Igor

    Установка специальных утилит не всегда удобна и не всегда приемлима. Выполнить XSLT можно в любом XSL-процессоре. В том числе и из почти любого скриптового языка. В командной строке опять же, кроме xmlstarlet есть ещё xsltproc и наверняка ещё что-то. В этом отношении иметь под рукой такой xsl — универсальнее.

    Однако за упоминание xmlindent спасибо!

    ОтветитьУдалить
  6. Использование XSLT универсально — спору нет. Но зачастую необходимые для этого средства не установлены на машине, и в этом случае установить маленький xmlindent проще. Кроме того это не требует писать XSLT-преобразований, как в первом способе. ;) Должен признать, однако, что xmllint — очень полезная утилита, и второй способ считаю приблизительно равным с третьим по удобству использования.

    ОтветитьУдалить
  7. Мне xmllint --format и сишный xmlindent тоже приглянулись. Не было бы уже готового скрипта, стал бы использовать их.

    ОтветитьУдалить