学习解析 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 上的源代码 手动安装。
使用 XMLStarlet 解析 XML
有许多工具旨在帮助解析和转换 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 选择数据
您可以使用 xmlstarlet select
命令(简写为 sel
)查看 XML 中的数据。 这是一个简单的 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 对其进行了详细文档记录,但我发现 Mozilla 的 XPath 文档 更简洁。
您可以使用方括号作为测试函数,将元素的内容与某个值进行比较。 这是对 <name>
元素值的测试,它仅返回与特定匹配关联的版本号。
假设示例 XML 文件包含以 1 开头的所有 Fedora 版本。 要查看与旧名称“Fedora Core”关联的所有版本号(该项目从版本 7 开始从名称中删除了“Core”)
$ 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
选项匹配的内容和您想要使用 --value-of
选项获取的数据值。
假设您知道 <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,它就越能作为一种强大而灵活的数据格式为您服务。
2 条评论