149

在编写 shell 脚本时,通常数据将位于单行记录文件中,例如 csv。grep使用和处理这些数据非常简单sed。但是我必须经常处理 XML,所以我真的想要一种通过命令行对 XML 数据进行脚本访问的方法。什么是最好的工具?

4

14 回答 14

106

我发现 xmlstarlet 在这类事情上非常擅长。

http://xmlstar.sourceforge.net/

也应该在大多数发行版存储库中可用。介绍性教程在这里:

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

于 2008-09-18T12:14:07.213 回答
37

一些有前途的工具:

  • nokogiri:使用 XPath 和 CSS 选择器在 ruby​​ 中解析 HTML/XML DOM

  • hpricot:已弃用

  • fxgrep:使用自己的类似 XPath 的语法来查询文档。用 SML 编写,因此安装可能很困难。

  • LT XML:派生自 SGML 工具的 XML 工具包,包括sggrepsgsortxmlnorm。使用自己的查询语法。文档 非常正式。用 C 语言编写。LT XML 2 声称支持 XPath、XInclude 和其他 W3C 标准。

  • xmlgrep2:使用 XPath 进行简单而强大的搜索。使用 XML::LibXML 和 libxml2 用 Perl 编写。

  • XQSharp:支持 XQuery,XPath 的扩展。为 .NET 框架编写。

  • xml-coreutils:Laird Breyer 的工具包,相当于 GNU coreutils。在一篇有趣的文章中讨论了理想的工具包应该包括什么。

  • xmldiff:用于比较两个 xml 文件的简单工具。

  • xmltk:在 debian、ubuntu、fedora 或 macports 中似乎没有包,自 2007 年以来没有发布,并且使用非便携式构建自动化。

xml-coreutils 似乎是文档最齐全且最面向 UNIX 的。

于 2008-09-18T11:39:59.260 回答
26

还有xml22xml对。它将允许通常的字符串编辑工具来处理 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>

PS 还有html2/ 2html

于 2010-06-22T22:01:13.587 回答
25

在 Joseph Holsten 的优秀列表中,我添加了 Perl 库 XML::XPath 附带的 xpath 命令行脚本。从 XML 文件中提取信息的好方法:

 xpath -q -e '/entry[@xml:lang="fr"]' *xml
于 2009-03-04T08:12:52.080 回答
16

您可以使用 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
于 2013-01-24T00:41:13.737 回答
9

如果您正在寻找 Windows 上的解决方案,Powershell 具有用于读取和写入 XML 的内置功能。

测试.xml:

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

Powershell脚本:

# 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

于 2013-07-29T21:29:56.547 回答
8

还有 NetBSD xmltools 的 xmlsed 和 xmlgrep!

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

于 2011-05-30T12:20:37.760 回答
6

完全取决于你想做什么。

XSLT 可能是要走的路,但有一个学习曲线。试试xsltproc,注意可以交参数。

于 2008-09-18T20:41:16.837 回答
4

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
于 2015-01-12T14:48:08.333 回答
4

D. Bohdan 维护一个开源 GitHub 存储库,其中包含用于结构化文本工具的命令行工具列表,其中有一个用于 XML/HTML 工具的部分:

https://github.com/dbohdan/structured-text-tools#xml-html

于 2019-09-21T04:38:17.600 回答
3

XQuery 可能是一个很好的解决方案。它(相对)容易学习并且是 W3C 标准。

我会推荐XQSharp作为命令行处理器。

于 2008-10-30T23:12:49.840 回答
3

我第一次使用xmlstarlet并且仍在使用它。当查询变得困难时,我需要 XML 的xpath2xquery功能支持我转向xidel http://www.videlibri.de/xidel.html

于 2017-03-16T03:21:13.483 回答
1

Grep 等价物

您可以定义一个 bash 函数,比如包装一些 python3 代码的“xp”(“xpath”)。要使用它,您需要安装 python3 和 python-lxml。好处:

  1. 您在例如 xmllint 中缺少的正则表达式匹配。
  2. 在命令行上用作过滤器(在管道中)

像这样使用它既简单又强大:

xmldoc=$(cat <<EOF
<?xml version="1.0" encoding="utf-8"?>
<job xmlns="http://www.sample.com/">programming</job>
EOF
)
selection='//*[namespace-uri()="http://www.sample.com/" and local-name()="job" and re:test(.,"^pro.*ing$")]/text()'
echo "$xmldoc" | xp "$selection"
# prints programming

xp() 看起来像这样:

xp()
{ 
local selection="$1";
local xmldoc;
if ! [[ -t 0 ]]; then
    read -rd '' xmldoc;
else
    xmldoc="$2";
fi;
python3 <(printf '%b' "from lxml.html import tostring\nfrom lxml import etree\nfrom sys import stdin\nregexpNS = \"http://exslt.org/regular-expressions\"\ntree = etree.parse(stdin)\nfor e in tree.xpath('""$selection""', namespaces={'re':regexpNS}):\n  if isinstance(e, str):\n    print(e)\n  else:\n    print(tostring(e).decode('UTF-8'))") <<< "$xmldoc"
}

Sed 等价物

考虑使用 xq,它可以为您提供 jq“编程语言”的全部功能。如果您安装了 python-pip,您可以使用 pip install yq安装 xq ,然后在下面的示例中,我们将“Keep Accounts”替换为“Keep Accounts 2”:

xmldoc=$(cat <<'EOF'
<resources>
    <string name="app_name">Keep Accounts</string>
    <string name="login">"login"</string>
    <string name="login_password">"password:"</string>
    <string name="login_account_hint">input to login</string>
    <string name="login_password_hint">input your password</string>
    <string name="login_fail">login failed</string>
</resources>
EOF
)
echo "$xmldoc" | xq '.resources.string = ([.resources.string[]|select(."#text" == "Keep Accounts") ."#text" = "Keep Accounts 2"])' -x
于 2020-03-14T16:03:53.020 回答
-1

JEdi​​t 有一个名为“XQuery”的插件,它为 XML 文档提供查询功能。

不完全是命令行,但它可以工作!

于 2008-09-18T11:47:15.890 回答