我正在尝试编辑/更新一些复杂的 XML,遗憾的是我无法更改其格式。我在 Bash 脚本中使用 XMLStarlet。
我遇到困难的是,当我尝试检索或编辑属性的 CDATA 值时,其中属性 "name={name}"
不唯一并返回多个值。
例如,我有以下 XML:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="key.xsl" ?>
<tables>
<tableset>
<table name="table1">
<row>
<fld name="fileName">
<strval><![CDATA[/my/XYZ/file1]]></strval>
</fld>
<fld name="fileName">
<strval><![CDATA[/my/XYZ/file2]]></strval>
</fld>
<fld name="fileName">
<strval><![CDATA[/my/other/XYZ/file3]]></strval>
</fld>
<fld name="worksBecauseUnique">
<strval><![CDATA[/XYZ/unique]]></strval>
</fld>
</row>
</table>
</tableset>
</tables>
使用 XMLStarlet 时,我可以轻松编辑以下值:
xmlstarlet ed -L \
-u '//tables/tableset/table/row/fld[@name="worksBecauseUnique"]/strval/text()' \
-v '/ABC/unique' \
myxmlfile.xml
但是,在尝试使用属性 name=fileName
修改任何 CDATA 值时遇到问题,因为 fileName
在 XML 中出现多次。
我希望得到如下输出:
<fld name="fileName">
<strval><![CDATA[/my/ABC/file1]]></strval>
</fld>
<fld name="fileName">
<strval><![CDATA[/my/ABC/file2]]></strval>
</fld>
<fld name="fileName">
<strval><![CDATA[/my/other/ABC/file3]]></strval>
</fld>
问题是,如果我尝试使用 XMLStarlet 更新 fileName
的 CDATA 值,如何更新每个值而不更新全部?
例如,如果我运行:
xmlstarlet ed -L \
-u "//tables/tableset/table/row/fld[@name=\"fileName\"]/strval/text()" \
-v "/my/ABC/file1" \
myxmlfile.xml
我得到以下不正确的输出:
<fld name="fileName">
<strval><![CDATA[/my/ABC/file1]]></strval>
</fld>
<fld name="fileName">
<strval><![CDATA[/my/ABC/file1]]></strval>
</fld>
<fld name="fileName">
<strval><![CDATA[/my/ABC/file1]]></strval>
</fld>
请注意每个 CDATA 值如何设置为 "/my/ABC/file1"
,其中我需要 "/my/ABC/file1"
, "/my/ABC/file2"
和 "/my/other/ABC/file3"
我希望以某种方式允许某人单独修改每个值...... 希望使用任何支持 XPath 的工具都可以实现这一点。
如有任何帮助,我们将不胜感激!
最佳答案
提供一个表达式(使用 -x
)将您的输入修改为您想要的输出:
xmlstarlet ed \
-u '//fld/strval[contains(., "/XYZ/")]' \
-x 'concat(substring-before(., "/XYZ/"), "/ABC/", substring-after(., "/XYZ/"))'
<in.xml >out.xml
顺便说一下,新版本的 XPath 标准中有更好的字符串替换函数;由于 libxml(由 XMLStarlet 使用)仅支持版本 1.0,因此该表达式比其他情况下有点笨拙。
关于xml - 使用 XMLStarlet 替换 XML 值内的子字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31835257/