我有以下形式的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}')
但我不知道如何合并它们。
答案 0 :(得分:1)
使用sed
或awk
进行XML解析是不安全的。这些工具非常灵活,但它们没有内置的XML解析功能。在sed
或awk
中实现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
属性“)。
第二个命令的输出是redirected到name
文件。
示例输入
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>