用于 XML 命令行处理的 Grep 和 Sed 等价物

在编写 shell 脚本时,数据通常位于单行记录(如 csv)的文件中。用 grepsed处理这些数据非常简单。但是我必须经常处理 XML,所以我非常希望能够通过命令行编写访问 XML 数据的脚本。最好的工具是什么?

74094 次浏览

一些有前途的工具:

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

  • Hpricot : 已弃用

  • Fxgrep : 使用它自己的类 XPath 语法来查询文档 安装可能有困难

  • LT XML : 源自 SGML 工具的 XML 工具包,包括 sggrepsgsort、, 使用自己的查询语法 使用 C. LT XML 2编写,声称支持 XPath,XInclude 以及其他 W3C 标准

  • Xmlgrep2 : 使用 XPath 进行简单而强大的搜索 和 libxml2.

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

  • Xml-coreutils : Laird Breyer 相当于 GNU 核心组件的工具包 关于理想工具包应该包括哪些内容的有趣的 论文

  • Xmldiff : 比较两个 xml 文件的简单工具

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

Xml-coreutils 似乎是最好的文档和最面向 UNIX 的。

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

虽然不完全是命令行,但是很管用!

我发现 xmlstarlet 在这方面很在行。

Http://xmlstar.sourceforge.net/

应该可以在大多数发行版存储库中找到,下面是一个介绍性的教程:

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

取决于你到底想做什么。

XSLT 可能是一种方法,但是有一个学习曲线。尝试 Xsltproc并注意您可以提交参数。

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

我建议使用 XQSharp作为命令行处理器。

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

 xpath -q -e '/entry[@xml:lang="fr"]' *xml

也有 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>

另外,还有 html2/2html

还有 NetBSD xmltools 的 xmlsed & xmlgrep!

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

可以使用 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

如果您正在寻找 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")

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

还有来自命令行 saxon-lint,它能够使用 XPath 3.0/XQuery 3.0(其他命令行工具使用 XPath 1.0)。

例子:

返回文章页面

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

Xml:

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

我最初使用 Xmlstarlet,现在仍在使用它。当查询变得困难,我需要 XML 的 Xpath2Xquery功能的支持,我转向 Xidelhttp://www.videlibri.de/xidel.html

Bohdan 维护了一个开源的 GitHub repo,其中保存了结构化文本工具的命令行工具列表,还有一个 XML/HTML 工具部分:

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

Grep 等效

您可以定义一个 bash 函数,比如说“ xp”(“ xpath”) ,它包装了一些 python3代码。要使用它,需要安装 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 安装 YQ安装 xq,那么在下面的示例中,我们将“ Keep Account”替换为“ Keep Account 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