Как красиво распечатать XML из командной строки?

449

Связанный: Как я могу печатать JSON в оболочке (unix) script?

Есть ли (unix) оболочка script для форматирования XML в удобочитаемой форме?

В принципе, я хочу, чтобы он преобразовал следующее:

<root><foo a="b">lorem</foo><bar value="ipsum" /></root>

... в нечто подобное:

<root>
    <foo a="b">lorem</foo>
    <bar value="ipsum" />
</root>
  • 0
    Чтобы xmllint доступен в системах Debian, вам необходимо установить пакет libxml2-utils ( libxml2 не предоставляет этот инструмент, по крайней мере, в Debian 5.0 "Lenny" и 6.0 "Squeeze").
Теги:
command-line

7 ответов

782
Лучший ответ

libxml2-utils

Эта утилита поставляется с libxml2-utils:

echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    xmllint --format -

Perl XML::Twig

Эта команда поставляется с модулем XML :: Twig , иногда пакетом xml-twig-tools:

echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    xml_pp

xmlstarlet

Эта команда поставляется с xmlstarlet:

echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    xmlstarlet format --indent-tab

tidy

Проверьте tidy пакет:

echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    tidy -xml -i -

питон

Python xml.dom.minidom может форматировать XML (как python2, так и python3):

echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    python -c 'import sys;import xml.dom.minidom;s=sys.stdin.read();print(xml.dom.minidom.parseString(s).toprettyxml())'

saxon-lint

Вам нужен saxon-lint:

echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    saxon-lint --indent --xpath '/' -

saxon-HE

Тебе нужен saxon-HE

 echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' |
    java -cp /usr/share/java/saxon/saxon9he.jar net.sf.saxon.Query \
    -s:- -qs:/ '!indent=yes'
  • 0
    Хороший, быстрый ответ. Первый вариант выглядит более распространенным в современных установках * nix. Незначительный момент; но можно ли его вызвать, не работая через промежуточный файл? То есть echo '<xml .. />' | xmllint --some-read-from-stdn-option ?
  • 0
    Смотрите мой отредактированный пост
Показать ещё 13 комментариев
113

xmllint --format yourxmlfile.xml

xmllint - это инструмент XML для командной строки, который включен в libxml2 (http://xmlsoft.org/).

================================================

Примечание. Если у вас не установлен libxml2 вы можете установить его, выполнив следующие действия:

CentOS

cd /tmp
wget ftp://xmlsoft.org/libxml2/libxml2-2.8.0.tar.gz
tar xzf libxml2-2.8.0.tar.gz
cd libxml2-2.8.0/
./configure
make
sudo make install
cd

Ubuntu

sudo apt-get install libxml2-utils

Cygwin

apt-cyg install libxml2

MacOS

Чтобы установить это на MacOS с Homebrew, просто выполните: brew install libxml2

Гит

Также доступно в Git, если вам нужен код: git clone git://git.gnome.org/libxml2

  • 4
    Ответ sputnick содержит эту информацию, но ответ crmpicco является наиболее полезным ответом на общий вопрос о том, как правильно печатать XML.
  • 2
    мы можем записать этот форматированный вывод xml в другой файл xml и использовать его .. например, xmllint --format yourxmlfile.xml >> new-file.xml
Показать ещё 2 комментария
33

Вы также можете использовать tidy, который, возможно, необходимо установить первым (например, на Ubuntu: sudo apt-get install tidy).

Для этого вы бы выпустили что-то вроде следующего:

tidy -xml -i your-file.xml > output.xml

Примечание. Имеет много дополнительных флагов читаемости, но поведение с переносом слов немного раздражает, чтобы распутать (http://tidy.sourceforge.net/docs/quickref.html).

  • 1
    Полезно, потому что я не смог заставить xmllint добавить разрывы строк в однострочный XML-файл. Спасибо!
  • 0
    tidy хорошо работает и для меня. В отличие от hxnormalize , это фактически закрывает <body> .
Показать ещё 2 комментария
11

Вы не указали файл, поэтому я предполагаю, что вы хотите предоставить строку XML в качестве стандартного ввода в командной строке. В этом случае сделайте следующее:

$ echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' | xmllint --format -
9

Чтобы иметь xmllint доступный в системах Debian, вам необходимо установить пакет libxml2-utils (libxml2 не предоставляет этот инструмент, по крайней мере, не на Debian 5.0 "Lenny" и 6.0 "Squeeze" ).

6

xmllint поддерживает форматирование на месте:

for f in *.xml; do xmllint -o $f --format $f; done

Как писал Даниэль Вейяр:

Я думаю, что xmllint -o tst.xml --format tst.xml должен быть безопасным, так как синтаксический анализатор полностью загрузит входные данные в дерево перед открытием выходных данных для его сериализации.

Уровень XMLLINT_INDENT контролируется XMLLINT_INDENT среды XMLLINT_INDENT которая по умолчанию имеет 2 пробела. Пример, как изменить отступ на 4 пробела:

XMLLINT_INDENT='    '  xmllint -o out.xml --format in.xml

Возможно, вам не хватает опции --recover когда ваши XML-документы повреждены. Или попробуйте слабый анализатор HTML со строгим выводом XML:

xmllint --html --xmlout <in.xml >out.xml

--nsclean, --nonet, --nocdata, --noblanks т.д. Могут быть полезны. Прочитайте справочную страницу.

apt-get install libxml2-utils
apt-cyg install libxml2
brew install libxml2
0

некоторые могут найти jtm быструю и быструю утилиту jtm: она конвертирует без потерь html/xml <-> json и поддерживает опцию отступа, например:

bash $ echo '<root><foo a="b">lorem</foo><bar value="ipsum" /></root>' | jtm | jtm -i5
<root>
     <foo a="b">lorem</foo>
     <bar value="ipsum"/>
</root>
bash $ 

Ещё вопросы

Сообщество Overcoder
Наверх
Меню