使用xmlstarlet追加XML节点,如何生成非自闭合node标签?
问题描述
现有如下XML文件:
<project> <node name="abc" description="abc-describe" tags="test-tag" osFamily="unix" osName="Ubuntu"> </node> <node name="def" description="def-describe" tags="test-tag" osFamily="unix" osName="Ubuntu"> </node> </project>
期望追加name="xyz"的node节点后,生成带有独立起始/闭合标签的格式:
<project> <node name="abc" description="abc-describe" tags="test-tag" osFamily="unix" osName="Ubuntu"> </node> <node name="def" description="def-describe" tags="test-tag" osFamily="unix" osName="Ubuntu"> </node> <node name="xyz" description="xyz-describe" tags="test-tag" osFamily="unix" osName="Ubuntu"> </node> </project>
但执行以下xmlstarlet命令后,生成的是自闭合标签的node元素:
<project> <node name="abc" description="abc-describe" tags="test-tag" osFamily="unix" osName="Ubuntu"> </node> <node name="def" description="def-describe" tags="test-tag" osFamily="unix" osName="Ubuntu"> </node> <node name="xyz" description="xyz-describe" tags="test-tag" osFamily="unix" osName="Ubuntu" /> </project>
所用命令:
xmlstarlet ed -L -s "/project" -t elem -n node -i "//node[3]" -t attr -n "name" -v "xyz" -i "//node[3]" -t attr -n "description" -v "xyz-describe" -i "//node[3]" -t attr -n "tags" -v "test-tag" -i "//node[3]" -t attr -n "osFamily" -v "unix" -i "//node[3]" -t attr -n "osName" -v "Ubuntu" file.xml
解决方法
原命令创建的是空元素,xmlstarlet默认对空元素采用自闭合标签格式。要生成独立的起始/结束标签,只需给新创建的node元素添加一个空白文本节点,使其不再是严格意义上的空元素。
修改后的命令如下(同时将定位方式改为//node[last()],避免原文件node数量变化导致的定位错误):
xmlstarlet ed -L -s "/project" -t elem -n node -v " " -i "//node[last()]" -t attr -n "name" -v "xyz" -i "//node[last()]" -t attr -n "description" -v "xyz-describe" -i "//node[last()]" -t attr -n "tags" -v "test-tag" -i "//node[last()]" -t attr -n "osFamily" -v "unix" -i "//node[last()]" -t attr -n "osName" -v "Ubuntu" file.xml
命令说明
-v " ":在创建node元素时直接添加空白文本内容,确保元素非空;//node[last()]:定位到project下最后一个node元素,比固定索引[3]更通用,适配原文件node数量变化的场景。
内容的提问来源于stack exchange,提问作者Vanaan
相关产品推荐
相关产品推荐

