You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止xmllint移除XML文件中的空白字符?

问题

之前已经能用xmllint批量修改XML文件中的指定属性,但这些文件存在大量冗余空白字符,xmllint会将其全部清理,导致git diff中出现多达50行修改,难以分辨功能性差异。有没有办法让xmllint仅修改目标属性值,同时保留原有空白格式?(已查阅xmllint手册,未找到对应选项)

示例

原始XML文件

<target_tags>
    <target_tag name="my_tag1" default="old_value1" />
    <target_tag name="my_tag2" default="old_value2" />
    <target_tag name="my_tag3" default="old_value3" />
</target_tags>

执行的xmllint命令

xmllint --shell /tmp/tmp.xml << EOF
cd //target_tag[@name="my_tag1"]/@default
set new_value
save
bye
EOF

修改后的XML文件

<target_tags>
    <target_tag name="my_tag1" default="new_value"/>
    <target_tag name="my_tag2" default="old_value2"/>
    <target_tag name="my_tag3" default="old_value3"/>
</target_tags>
解决方案

xmllint基于libxml2实现,其核心逻辑会强制规范XML结构,无法做到仅修改属性而完全保留原始空白和格式。推荐使用以下两种替代方案:

1. xmlstarlet(推荐,适用于所有XML场景)

xmlstarlet支持在修改XML时默认保留原始格式(除非主动指定格式化参数)。安装后执行以下命令即可完成修改:

xmlstarlet edit --inplace \
  --update "//target_tag[@name='my_tag1']/@default" \
  --value "new_value" \
  /tmp/tmp.xml

该命令仅会修改目标属性值,原始的换行、缩进、标签结尾空格等格式都会完整保留。

2. sed(仅适用于结构简单的XML)

如果你的XML结构固定(属性顺序不变、无跨换行的属性定义),可以用sed直接做文本替换,避免XML解析带来的格式变更:

sed -i 's/\(<target_tag name="my_tag1" default="\)[^"]*"/\1new_value"/' /tmp/tmp.xml

注意:这种方法有局限性,若XML结构出现属性顺序调整、属性跨行等情况,sed会失效,仅建议用于简单场景。

内容的提问来源于stack exchange,提问作者Will1v

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 16:20:10