Поиск по сайту:

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

Статьи по данной тематике: