如果你经常需要在Linux服务器上处理XML配置文件、解析API返回数据,或者批量调整XML结构,那么xmlstarlet绝对值得放进你的工具箱。这个基于libxml2的命令行工具把XPath的强大能力带到了shell环境中,一条命令就能完成原本需要写脚本才能做的事。接下来我会从安装开始,手把手演示几个最常用的操作场景。

安装与基本用法
在Debian或Ubuntu系统上,直接使用apt安装即可:
sudo apt update sudo apt install xmlstarlet
在CentOS或RHEL系发行版中,可以通过yum或dnf安装:
sudo yum install xmlstarlet # 或者 sudo dnf install xmlstarlet
安装完成后,执行xmlstarlet --version可以查看版本信息。xmlstarlet提供了一系列子命令,每个子命令对应一种操作类型。最常用的三个是sel(select,查询)、ed(edit,编辑)和fo(format,格式化)。另外还有val(validate,校验)、tr(transform,XSLT转换)等。如果你记不住子命令,直接运行xmlstarlet不带参数,会列出所有可用子命令的简要说明。
为了演示,我们先创建一个简单的XML文件books.xml,内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="编程">
<title lang="zh">深入理解计算机系统</title>
<author>Randal E. Bryant</author>
<year>2016</year>
<price>139.00</price>
</book>
<book category="小说">
<title lang="zh">三体</title>
<author>刘慈欣</author>
<year>2008</year>
<price>23.00</price>
</book>
</bookstore>
这个文件包含两本书的信息,每本书都有category属性、title、author、year和price子节点。后面所有示例都会基于这个文件。
使用xmlstarlet查询XML
查询操作使用sel子命令,配合-t(template)和-v(value-of)来输出节点内容。最简单的用法是提取所有title节点的文本:
xmlstarlet sel -t -v "//title" books.xml
这条命令会依次输出两个title节点的内容,输出结果会连在一起没有换行。如果希望每个结果单独一行,可以加上-n选项或者在模板中使用<xsl:text>,但在sel的简化语法里,常用-n表示换行:
xmlstarlet sel -t -v "//title" -n books.xml
XPath表达式是xmlstarlet查询的灵魂。比如只想获取category属性为“编程”的书名,可以这样写:
xmlstarlet sel -t -v "//book[@category='编程']/title" -n books.xml
如果需要同时输出多个字段,可以在一个模板中使用多个-v,并用-o插入自定义分隔符。例如输出每本书的标题和价格,中间用冒号分隔:
xmlstarlet sel -t -m "//book" -v "title" -o ":" -v "price" -n books.xml
这里的-m表示match,对每个匹配的节点执行后面的操作,相当于循环。输出结果会像这样:
深入理解计算机系统:139.00 三体:23.00
除了提取文本,还可以提取属性值。使用@属性名即可:
xmlstarlet sel -t -v "//book/@category" -n books.xml
如果你想把查询结果保存到变量中供脚本使用,直接使用命令替换就行,比如title=$(xmlstarlet sel -t -v "//book[1]/title" books.xml)。
使用xmlstarlet编辑XML
编辑操作通过ed子命令完成。xmlstarlet的编辑命令不会直接修改原文件,而是把修改后的结果输出到标准输出,你需要使用重定向或者-L(或--inplace)选项直接写回原文件。如果直接使用-L,修改前最好先备份,因为操作是不可逆的。
先来看怎么修改一个节点的文本值。下面的命令把第一本书的价格改成150.00:
xmlstarlet ed -u "//book[1]/price" -v "150.00" books.xml
执行后终端会打印出修改后的完整XML内容,但原文件并没有变化。如果希望直接更新原文件,加上-L:
xmlstarlet ed -L -u "//book[1]/price" -v "150.00" books.xml
修改属性值使用-u配合@属性名。比如把第二本书的category改为“科幻”:
xmlstarlet ed -u "//book[2]/@category" -v "科幻" books.xml
添加新节点使用-s(subnode)或-a(append)。-s可以在指定节点下创建子节点,-a则在指定节点后添加兄弟节点。给第一本书添加一个<publisher>子节点:
xmlstarlet ed -s "//book[1]" -t elem -n "publisher" -v "机械工业出版社" books.xml
其中-t elem指定节点类型为元素,-n指定节点名,-v指定文本值。注意节点值必须用引号包含,如果值里有空格也没关系。
删除节点使用-d。删除第二本书的<year>节点:
xmlstarlet ed -d "//book[2]/year" books.xml
这些编辑命令可以组合使用,一条命令完成多个修改。比如同时修改价格、添加新节点并删除另一个节点:
xmlstarlet ed -L \ -u "//book[1]/price" -v "129.00" \ -s "//book[1]" -t elem -n "isbn" -v "978-7-111-54493-7" \ -d "//book[2]/year" \ books.xml
编辑命令配合XPath可以精准定位,但如果XML结构复杂,建议先使用sel验证XPath写法,确认命中目标节点后再执行ed,避免误操作。
格式化与校验XML
手写的XML往往缩进混乱,读起来费劲。fo子命令可以一键格式化,让文档结构变得清晰。用法很简单:
xmlstarlet fo books.xml
如果原始文件没有任何换行和缩进,这条命令会输出层次分明的XML。还可以加上-s 2指定每级缩进两个空格,或者-t使用制表符缩进。
校验XML是否合法使用val子命令。比如检查格式是否正确:
xmlstarlet val books.xml
如果XML有语法错误,val会输出错误位置和原因。对于大型XML文件,校验可以帮助快速定位问题。另外如果有DTD或XSD约束,可以加上-d或-s参数进行更严格的验证。
掌握了这些基础操作后,你完全可以把xmlstarlet集成到自动化脚本里,例如批量修改配置文件的某个字段、从日志中提取数据,或者校验上游系统生成的XML文件。相比用Python写XML解析脚本,xmlstarlet往往只需要一行命令,开发和维护成本都更低。
xmlstarlet命令行工具XML编辑修改时间:2026-09-23 08:37:45