我正在尝试使用
sed
命令更改 XML 中的标签值。我也使用了xmlstarlet
,但由于 CDATA 标签而没有帮助。下面是标签。
但是 xmlstarlet 将
<
更改为 <
,并将 >
更改为 >
。
xmlstarlet ed -u '//item[@name]/val' -v '<![CDATA[1234]]>' file.xml
示例输入:
file.xml
<item name="Rx_Frequency">
<val><![CDATA[xxx]]></val>
</item>
实际产量:
<item name="Rx_Frequency">
<val><\![CDATA[1234]]></val>
</item>
预期输出:
<item name="Rx_Frequency">
<val><![CDATA[1234]]></val>
</item>
xmllint
也可以用
printf '%s\n' 'cd //item[@name]/val' 'set <![CDATA[1234]]>' 'save' 'bye' | xmllint --shell tmp.xml
命令输出
/ > cd //item[@name]/val
val > set <![CDATA[1234]]>
val > save
val > bye
结果
<item name="Rx_Frequency">
<val><![CDATA[1234]]></val>
</item>
与
xmlstarlet
。我假设您的文件不使用 namespaces。
xmlstarlet edit --omit-decl \
--update '//item[@name]/val' --value '<![CDATA[1234]]>' file.xml | xmlstarlet unescape
输出:
<item name="Rx_Frequency">
<val><![CDATA[1234]]></val>
</item>
参见:
xmlstarlet unescape --help
NB:这是一个粗略的黑客行为,而不是建议。
xmlstarlet edit
接受不规则元素名称(它不是 XSLT
处理器),因此可以通过插入来创建 CDATA
部分
一个具有奇怪名称的空元素并让 sed
修复
部分结束标记:
printf '%s\n' '<doc><v>x</v></doc>' |
xmlstarlet edit -O -P \
--var T '*/*' \
-d '$T/text()' \
-s '$T' -t elem -n '![CDATA[1234 <"'\''>]]' -v '' |
sed 's,]]/>,]]>,g'
输出:
<doc><v><![CDATA[1234 <"'>]]></v></doc>
由于
]]/>
可能出现在 XML 输入中的 CDATA
部分中,因此安全
方法是确保它尚不存在。