xmlstarlet insert无报错但执行失败,XML文件内容被清空
问题分析与解决
问题描述
现有channels.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?> <ChannelList> <channel> <tvg-logo>https://tvpmlogopus.samsungcloud.tv/platform/image/sourcelogo/vc/70/01/68/USAJ2200014K9_20201208T081550.png</tvg-logo> <group-title>Samsung TV Plus</group-title> <title>US | ION Plus</title> <url>https://live-news-manifest.tubi.video/live-news-manifest/csm/extlive/tubiprd01,ION-Plus.m3u8</url> </channel> <channel> <tvg-logo>https://od.lk/s/MF8yMjY0NDYwOTdf/Stirr_Blue_510x510.png</tvg-logo> <group-title>"STIRR TV",STIRR</group-title> <title>Electric Now</title> <url>https://dai.google.com/linear/hls/event/KsvJAc81Qoewj6opYso6Fw/master.m3u8</url> </channel> </ChannelList>
执行以下xmlstarlet命令试图添加元素:
xmlstarlet ed -L -i "/ChannelList/channel/title/" -v "NewTitle" > channels.xml
执行后无报错,但channels.xml被清空,终端输出xmlstarlet的帮助信息。无论是否添加-L参数,文件都会被清空。运行环境为Docker容器,文件属主为root,权限777。
错误原因
- 未指定输入文件:xmlstarlet的
ed编辑子命令必须明确指定要处理的XML文件路径,你的命令未提供输入文件,导致xmlstarlet无法读取内容,直接输出帮助信息。 - 重定向与
-L参数冲突:-L是原地编辑参数(直接修改原文件),此时不能使用> channels.xml重定向输出——bash会在执行命令前先截断目标文件,导致原文件被清空,而xmlstarlet因未获取到输入内容,最终文件内容为空。 -i参数用法不完整:-i(插入节点)需要配合-t指定节点类型(如elem表示元素节点)、-n指定新节点名称,仅使用-v设置节点值会导致参数缺失,触发xmlstarlet输出帮助信息。
正确命令示例
假设你需要在每个<title>节点之前插入一个<new-title>NewTitle</new-title>元素,可使用以下命令:
原地编辑(直接修改原文件)
使用-L参数直接修改原文件,无需重定向:
xmlstarlet ed -L -i "/ChannelList/channel/title" -t elem -n new-title -v "NewTitle" channels.xml
输出到新文件(保留原文件)
若需保留原文件,将结果输出到新文件,不要使用-L参数:
xmlstarlet ed -i "/ChannelList/channel/title" -t elem -n new-title -v "NewTitle" channels.xml > new_channels.xml
参数说明
-L:原地编辑原文件,修改内容直接保存到源文件-i <xpath>:在指定XPath匹配的节点之前插入新节点-t elem:声明要插入的是元素类型节点-n new-title:指定新元素的节点名称-v "NewTitle":设置新元素的文本内容- 命令末尾的
channels.xml是要处理的输入文件路径
内容的提问来源于stack exchange,提问作者sturmey
相关产品推荐
相关产品推荐

