在Bash中添加XML属性

时间:2016-10-28 13:52:32

标签: linux bash xml-parsing

我有以下形式的XML数据:

<string name="app_name">my App</string>
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="done">Done</string>

我正在尝试编写一个Bash脚本,用于将XML转换为以下内容:

<string comment="for more see http://www.web.com/test/app_name" name="app_name">my App</string>
<string comment="for more see http://www.web.com/test/yes" name="yes">Yes</string>

我做了一些搜索,这是我到目前为止所发现的。

下面的代码是替换每个元素:

 sed -i 's/<string/<string comment=\"for more see http:\/\/www\.web\.com\/test\/\"    /g' string.xml

此表达式获取name属性:

Sname=$(sed '/name/s/\(.*name=\)\(.*\)/\2/' string.xml|awk -F\" '{print $2}')

但我不知道如何合并它们。

1 个答案:

答案 0 :(得分:1)

使用sedawk进行XML解析是不安全的。这些工具非常灵活,但它们没有内置的XML解析功能。在sedawk中实现XML解析器非常繁琐且不切实际。我建议使用XML解析器,例如xmlstarlet(实际上不仅仅是解析器)。

示例

xmlstarlet ed -a '//string[@name]' -t attr -n comment src.xml | \
  xmlstarlet ed -u '//string/@comment' \
  -x 'concat("see http://www.web.com/test/app_name/", ../@name)' > out.xml

第一个xmlstarlet命令解析src.xml文件,将空comment属性附加到具有string属性的所有name标记(使用'//string[@name]' XPath表达式)。该命令的输出通过pipeline|)传递给第二个命令。

第二个命令从管道读取XML,并使用concat()函数更新comment属性,特别是将静态字符串"see http://www.web.com/test/app_name/"与{{1}的值连接起来} {}属性(name代表父节点的 ../@name属性“)。

第二个命令的输出是redirectedname文件。

示例输入

out.xml

示例输出

<root x="10">
  <string name="app_name">my App</string>
  <string name="yes">Yes</string>
  <string name="no">No</string>
  <string name="done">Done</string>
</root>