Используйте XMLStarlet для анализа XML в терминале Linux
Станьте звездой XML с XMLStarlet, набором инструментов XML для вашего терминала.
Обучение анализу XML часто считается сложной задачей, но это не обязательно. XML высоко и строго структурирован, поэтому он относительно предсказуем. Существует также множество инструментов, которые помогут сделать работу управляемой.
Одна из моих любимых утилит XML — XMLStarlet, набор инструментов XML для вашего терминала. С помощью XMLStarlet вы можете проверять, анализировать, редактировать, форматировать и преобразовывать данные XML. XMLStarlet — относительно минимальная команда, но навигация по XML полна возможностей, поэтому в этой статье показано, как использовать ее для запроса данных XML.
Установить
XMLStarlet установлен по умолчанию в CentOS, Fedora и многих других современных дистрибутивах Linux, поэтому просто откройте терминал и введите xmlstarlet
, чтобы получить к нему доступ. Если XMLStarlet еще не установлен, ваша операционная система предложит установить его самостоятельно.
Альтернативно вы можете установить команду xmlstarlet
из менеджера пакетов:
$ sudo dnf install xmlstarlet
В macOS используйте MacPorts или Homebrew. В Windows используйте Chocolatey.
Если ничего не помогает, вы можете установить его вручную из исходного кода на Sourceforge.
Анализ XML с помощью XMLStarlet
Существует множество инструментов, предназначенных для анализа и преобразования XML-данных, включая программные библиотеки, позволяющие писать собственные анализаторы и сложные команды, такие как fop
и xsltproc
. Однако иногда вам не нужно обрабатывать данные XML; вам просто нужен удобный способ извлечь важные данные, обновить или просто проверить их. Для спонтанного взаимодействия с XML я использую xmlstarlet
, классическое приложение в стиле «швейцарского ножа», которое выполняет наиболее распространенные задачи XML. Вы можете увидеть, что он может предложить, выполнив команду с опцией --help
:
$ xmlstarlet --help
Usage: xmlstarlet [<options>] <command> [<cmd-options>]
where <command> is one of:
ed (or edit) - Edit/Update XML document(s)
sel (or select) - Select data or query XML document(s) (XPATH, etc)
tr (or transform) - Transform XML document(s) using XSLT
val (or validate) - Validate XML document(s) (well-formed/DTD/XSD/RelaxNG)
fo (or format) - Format XML document(s)
el (or elements) - Display element structure of XML document
c14n (or canonic) - XML canonicalization
ls (or list) - List directory as XML
[...]
Дополнительную помощь можно получить, добавив --help
в конец любой из этих подкоманд:
$ xmlstarlet sel --help
-Q or --quiet - do not write anything to standard output.
-C or --comp - display generated XSLT
-R or --root - print root element <xsl-select>
-T or --text - output is text (default is XML)
-I or --indent - indent output
[...]
Выбор данных с помощью sel
Вы можете просмотреть данные в формате XML с помощью команды xmlstarlet select
(сокращенно sel
). Вот простой XML-документ:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xml>
<os>
<linux>
<distribution>
<name>Fedora</name>
<release>7</release>
<codename>Moonshine</codename>
<spins>
<name>Live</name>
<name>Fedora</name>
<name>Everything</name>
</spins>
</distribution>
<distribution>
<name>Fedora Core</name>
<release>6</release>
<codename>Zod</codename>
<spins></spins>
</distribution>
</linux>
</os>
</xml>
При поиске данных в файле XML ваша первая задача — сосредоточиться на узле, который вы хотите изучить. Если вы знаете путь к узлу, укажите полный путь с помощью опции --value-of
. Чем раньше вы начнете исследовать дерево объектной модели документа (DOM), тем больше информации вы увидите:
$ xmlstarlet select --template \
--value-of /xml/os/linux/distribution \
--nl myfile.xml
Fedora
7
Moonshine
Live
Fedora
Everything
Fedora Core
6
Zod
--nl
означает «новая строка» и вставляет большое количество пробелов, чтобы гарантировать, что приглашение терминала получит новую строку после получения результатов. Я удалил часть лишнего пространства в образец вывода.
Сузьте фокус, спустившись дальше в дерево DOM:
$ xmlstarlet select --template \
--value-of /xml/os/linux/distribution/name \
--nl myfile.xml
Fedora
Fedora Core
Условный выбор
Один из самых мощных инструментов для навигации и анализа XML называется XPath. Он управляет синтаксисом, используемым при поиске XML, и вызывает функции из библиотек XML. XMLStarlet понимает выражения XPath, поэтому вы можете сделать свой выбор условным с помощью функции XPath. XPath обладает множеством функций и подробно документирован W3C, но я считаю документацию по XPath Mozilla более краткой.
Вы можете использовать квадратные скобки в качестве проверочной функции, сравнивая содержимое элемента с некоторым значением. Ниже приведен тест значения элемента <name>
, который возвращает номер выпуска, связанный только с определенным совпадением.
Представьте на мгновение, что пример XML-файла содержит все выпуски Fedora, начинающиеся с 1. Чтобы просмотреть все номера выпусков, связанные со старым названием «Fedora Core» (в проекте было удалено «Core» из названия, начиная с выпуска 7):
$ xmlstarlet sel --template \
--value-of '/xml/os/linux/distribution[name = "Fedora Core"]/release' \
--nl myfile.xml
6
5
4
3
2
1
Вы также можете просмотреть все кодовые имена для этих выпусков, изменив путь --value-of
на /xml/os/linux/distribution[name="Fedora Core"]/codename
.
Сопоставление путей и получение значений
Преимущество просмотра тегов XML как узлов состоит в том, что, найдя узел, вы можете думать о нем как о своем текущем «каталоге» данных. На самом деле это не каталог, по крайней мере, в смысле файловой системы, а набор данных, к которым вы можете обращаться. Чтобы помочь вам разделить пункт назначения и данные «внутри» него, XMLStarlet различает то, что вы пытаетесь сопоставить с помощью параметра --match
, и значение нужных данных с помощью --значение
.
Предположим, вы знаете, что узел <spin>
содержит несколько элементов. Это делает его вашим пунктом назначения. Оказавшись там, вы можете использовать --value-of
, чтобы указать, для какого элемента вы хотите получить значение. Чтобы просмотреть все элементы, используйте точку (.
), обозначающую ваше текущее местоположение:
$ xmlstarlet sel --template \
--match '/xml/os/linux/distribution/spin' \
--value-of '.' --nl myfile.xml \
Live
Fedora
Everything
Как и при навигации по DOM, вы можете использовать выражения XPath, чтобы ограничить объем возвращаемых данных. В этом примере я использую функцию last()
для получения только последнего элемента в узле spin
:
$ xmlstarlet select --template \
--match '/xml/os/linux/distribution/spin' \
--value-of '*[last()]' --nl myfile.xml
Everything
В этом примере я использую функцию position()
для выбора определенного элемента в узле spin
:
$ xmlstarlet select --template \
--match '/xml/os/linux/distribution/spin' \
--value-of '*[position() = 2]' --nl myfile.xml
Fedora
Параметры --match
и --value-of
могут перекрываться, поэтому вам решать, как вы хотите использовать их вместе. Эти два выражения в примере XML делают одно и то же:
$ xmlstarlet select --template \
--match '/xml/os/linux/distribution/spin' \
--value-of '.' \
--nl myfile.xml
Live
Fedora
Everything
$ xmlstarlet select --template \
--match '/xml/os/linux/distribution' \
--value-of 'spin' \
--nl myfile.xml
Live
Fedora
Everything
Освоение XML
XML может иногда показаться слишком многословным и громоздким, но инструменты, созданные для взаимодействия с ним, неизменно удивляют меня. Если вы хотите воспользоваться преимуществами XML, то XMLStarlet может стать хорошей отправной точкой. В следующий раз, когда вы собираетесь открыть XML-файл для просмотра структурированных данных, попробуйте использовать XMLStarlet и посмотрите, сможете ли вы вместо этого запросить эти данные. Чем удобнее вы будете работать с XML, тем лучше он сможет служить вам в качестве надежного и гибкого формата данных.