如何用xmlstarlet将多<value>节点合并为带---分隔的单个节点?
解决xmlstarlet合并节点并保留标签的问题
你的问题出在原命令直接更新了<attr>节点本身,导致原有的<value>子节点被替换成了合并后的文本。要保留<value>标签,需要针对<value>节点操作,而不是<attr>节点。
方法一:适用于任意数量的节点
这个方法先删除所有原有<value>节点,再插入一个包含合并后内容的新<value>节点:
xmlstarlet ed \ -d "//attr[@name='code']/value" \ -s "//attr[@name='code']" -t elem -n value -v "$(xmlstarlet sel -t -m "//attr[@name='code']/value" -v . -o "---" input.xml | sed 's/---$//')" input.xml
命令拆解:
-d "//attr[@name='code']/value":删除目标<attr>下的所有<value>子节点-s "//attr[@name='code']" -t elem -n value:在<attr>节点下新建一个<value>元素- 括号内的子命令:
xmlstarlet sel -t -m "//attr[@name='code']/value" -v . -o "---":遍历每个<value>节点,输出其文本并追加---分隔符sed 's/---$//':移除末尾多余的---
方法二:适用于固定数量的节点
如果你的<value>节点数量固定(比如2个),可以直接更新第一个<value>的内容,再删除其他节点:
xmlstarlet ed \ -u "//attr[@name='code']/value[1]" -x "concat(value[1], '---', value[2])" \ -d "//attr[@name='code']/value[position()>1]" input.xml
效果示例
假设原XML内容:
<root> <attr name="code"> <value>CODE1</value> <value>CODE2</value> <value>CODE3</value> </attr> </root>
处理后会变成:
<root> <attr name="code"> <value>CODE1---CODE2---CODE3</value> </attr> </root>
内容的提问来源于stack exchange,提问作者Carlos Otero
相关产品推荐
相关产品推荐

