Эквивалент Grep и Sed для обработки командной строки XML

125

При выполнении сценариев оболочки обычно данные будут содержаться в файлах с одиночной линией, таких как csv. Очень просто обрабатывать эти данные с помощью grep и sed. Но мне приходится иметь дело с XML часто, поэтому мне действительно нравится способ доступа к данным XML через script через командную строку. Каковы лучшие инструменты?

Теги:
scripting
command-line

13 ответов

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

Я обнаружил, что xmlstarlet очень хорош в этом.

http://xmlstar.sourceforge.net/

Должен быть доступен и в большинстве репозиториев дистрибутивов. Вводный учебник находится здесь:

http://www.ibm.com/developerworks/library/x-starlet.html

  • 1
    Я подумал, что на сайте Sourceforge есть бинарные файлы для Windows.
  • 0
    Хотя, насколько я могу судить, XQuery не поддерживает.
Показать ещё 2 комментария
29

Некоторые перспективные инструменты:

  • nokogiri: разбор HTML/XML DOM в рубине с помощью селекторов XPath и CSS

  • hpricot: устаревший

  • fxgrep: Использует собственный синтаксис XPath для запроса документов. Написано в SML, поэтому установка может быть затруднена.

  • LT XML: Инструментарий XML, полученный из инструментов SGML, включая sggrep, sgsort, xmlnorm и другие. Использует свой собственный синтаксис запросов. Документация очень формальный. Написано в C. LT XML 2 утверждает поддержку XPath, XInclude и другие стандарты W3C.

  • xmlgrep2: простой и мощный поиск с помощью XPath. Написано в Perl, используя XML:: LibXML и libxml2.

  • XQSharp: Поддерживает XQuery, расширение для XPath. Написано для .NET Framework.

  • xml-coreutils: Набор инструментов Laird Breyer, эквивалентный GNU coreutils. Обсуждается в интересный эссе о том, что должен включать идеальный инструментарий.

  • xmldiff: Простой инструмент для сравнения двух файлов xml.

  • xmltk: похоже, нет пакета в debian, ubuntu, fedora или macports, не был выпущен с 2007 года и использует не переносимую автоматизацию сборки.

xml-coreutils кажется наиболее документированным и ориентированным на UNIX.

  • 1
    Не могли бы вы создать скрипт-обертку для программы Ruby и передать массив аргументов в скрипте hpricot? Например, в сценарии оболочки PHP должно работать что-то вроде следующего: <? Php / path / to / hpricot $ argv?>
23

Существует также пара xml2 и 2xml. Это позволит обычным инструментам редактирования строк обрабатывать XML.

Пример. q.xml:

<?xml version="1.0"?>
<foo>
    text
    more text
    <textnode>ddd</textnode><textnode a="bv">dsss</textnode>
    <![CDATA[ asfdasdsa <foo> sdfsdfdsf <bar> ]]>
</foo>

xml2 < q.xml

/foo=
/foo=   text
/foo=   more text
/foo=   
/foo/textnode=ddd
/foo/textnode
/foo/textnode/@a=bv
/foo/textnode=dsss
/foo=
/foo=    asfdasdsa <foo> sdfsdfdsf <bar> 
/foo=

xml2 < q.xml | grep textnode | sed 's!/foo!/bar/baz!' | 2xml

<bar><baz><textnode>ddd</textnode><textnode a="bv">dsss</textnode></baz></bar>

P.S. Есть также html2/2html.

  • 0
    Вы говорите об этом xml2? ofb.net/~egnor/xml2
  • 0
    @ Джозеф Холстен Да. Это позволяет взламывать XML, не продумывая XPath.
Показать ещё 3 комментария
23

К Джозефу Холстен отличный список, я добавляю xpath-командную строку script, которая поставляется с библиотекой Perl XML:: XPath. Отличный способ извлечь информацию из XML файлов:

 xpath -q -e '/entry[@xml:lang="fr"]' *xml
  • 3
    Он устанавливается по умолчанию в osx, но без параметров -q -e . Пример, получить значение атрибута «package» из узла «manifest» в «AndroidManifest.xml»: xpath AndroidManifest.xml 'string(/manifest/@package)' 2> /dev/null
9

Вы можете использовать xmllint:

xmllint --xpath //title books.xml

Должен быть связан с большинством дистрибутивов, а также связан с Cygwin.

$ xmllint --version
xmllint: using libxml version 20900

См:

$ xmllint
Usage : xmllint [options] XMLfiles ...
        Parse the XML files and output the result of the parsing
        --version : display the version of the XML library used
        --debug : dump a debug tree of the in-memory document
        ...
        --schematron schema : do validation against a schematron
        --sax1: use the old SAX1 interfaces for processing
        --sax: do not build a tree but work just at the SAX level
        --oldxml10: use XML-1.0 parsing rules before the 5th edition
        --xpath expr: evaluate the XPath expression, inply --noout
  • 2
    Для --xpath нет аргумента xmllint : manpagez.com/man/1/xmllint
  • 0
    @MiserableVariable: страница справочника неверна. Я только что посмотрел справочную страницу для моей версии: аргумент xpath не указан. Это ошибка документации. Попробуйте запустить программу.
Показать ещё 2 комментария
5

Если вы ищете решение для Windows, Powershell имеет встроенные функции для чтения и записи XML.

test.xml:

<root>
  <one>I like applesauce</one>
  <two>You sure bet I do!</two>
</root>

Powershell script:

# load XML file into local variable and cast as XML type.
$doc = [xml](Get-Content ./test.xml)

$doc.root.one                                   #echoes "I like applesauce"
$doc.root.one = "Who doesn't like applesauce?"  #replace inner text of <one> node

# create new node...
$newNode = $doc.CreateElement("three")
$newNode.set_InnerText("And don't you forget it!")

# ...and position it in the hierarchy
$doc.root.AppendChild($newNode)

# write results to disk
$doc.save("./testNew.xml")

testNew.xml:

<root>
  <one>Who likes applesauce?</one>
  <two>You sure bet I do!</two>
  <three>And don't you forget it!</three>
</root>

Источник: https://serverfault.com/questions/26976/update-xml-from-the-command-line-windows

  • 0
    Несколько часов сражался с различными инструментами Linux, прежде чем прибегнуть к Powershell. Я удивлен, что это так сложно - linux cmd-line обычно очень хорош, но здесь, похоже, есть дыра. Примечание: вариант использования для меня был: 1) найти узлы по xpath, 2) удалить, если найден, 3) добавить новые узлы, 4) сохранить файл. Я обновлял кучу конфигов solr. Если кто-нибудь знает простой / надежный способ сделать это, я весь слух
  • 0
    Вау, это действительно на цыпочках до линии приемлемого решения. Но, честно говоря, я бы, вероятно, согласился бы, если бы это выглядело как xps $doc .root.one xps $doc 'AppendChild("three")' и xps $doc '.three.set_InnerText("And don't you forget it!")' , что явно уступает!
5

Также есть xmlsed и xmlgrep для xmltools NetBSD!

http://blog.huoc.org/xmltools-not-dead.html

5

В зависимости от того, что вы хотите сделать.

XSLT может быть способом, но есть кривая обучения. Попробуйте xsltproc и обратите внимание, что вы можете использовать параметры.

2

Там также saxon-lint из командной строки с возможностью использования XPath 3.0/XQuery 3.0. (Другие средства командной строки используют XPath 1.0).

ПРИМЕРЫ:

HTTP/HTML:

$ saxon-lint --html --xpath 'count(//a)' http://stackoverflow.com/q/91791
328

xml:

$ saxon-lint --xpath '//a[@class="x"]' file.xml
2

XQuery может быть хорошим решением. Это (относительно) легко учиться и является стандартом W3C.

Я бы рекомендовал XQSharp для процессора командной строки.

  • 1
    BaseX также имеет процессор XQuery для командной строки (в дополнение к режиму базы данных) и соответствует новейшим версиям стандарта (достаточно близко следуя развивающемуся проекту XQuery 3.0).
0

Сначала я использовал xmlstarlet и все еще использую его. Когда запрос становится жестким, мне нужна поддержка XML xpath2 и xquery. Я перехожу к xidel http://www.videlibri.de/xidel.html p >

0

JEdit имеет плагин под названием "XQuery", который предоставляет функции запросов для документов XML.

Не совсем командной строки, но она работает!

  • 0
    Хотя JEdit, вероятно, имеет способ поиска по файлу, он не делает его конкурентом grep(1) .
0

Определите, какие операции вы хотите делать в файлах XML и создайте script (возможно, в Python, Perl), который предоставляет эту функциональность с помощью аргументов для использования сценариев оболочки.

Ещё вопросы

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