使用xmlstarlet替换XML中的标记值



我正在尝试将input.xml中的值test替换为lookup。脚本正在执行,没有任何错误,但没有替换该值。

sed -i '/<Filter>/,/</Filter>/s/test/lookup/' input.xml > input_1.xml

下面是我的input.xml文件:

<NikuDataBus
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="./src/webroot/WEB-INF/xog/xsd/nikuxog_entity.xsd">
<Header version="14.2" action="read" objectType="contentPack" externalSource="NIKU"/>
<LookupQuery>
<Filter name="code" criteria="EQUALS">test</Filter>
</LookupQuery>
</NikuDataBus>

使用像sed这样的非语法感知工具解析XML是个坏主意。解决方案是XML格式有一点变化。使用xmlstarlet,这是一种语法识别工具,用于编辑文件。

由于您的文件在语法上也是有效的,因此解决问题非常简单。只做

xmlstarlet edit --update '//NikuDataBus/LookupQuery/Filter' --value 'lookup' input.xml

要像sed -i一样就地编辑文件,如果您的版本支持,请对解决方案使用-L标志,或者使用临时文件(> temp && mv temp input.xml(

xmlstarlet edit -L --update '//NikuDataBus/LookupQuery/Filter' --value 'lookup' input.xml 

或者,如果Filter标签包含test,则可以更进一步,仅替换,这可以作为执行

xmlstarlet edit --update '//NikuDataBus/LookupQuery/Filter[contains(.,"test")]' --value 'lookup' input.xml

在以下版本的Centos 7上进行了测试。

$ xmlstarlet --version
compiled against libxml2 2.9.1, linked with 20901
compiled against libxslt 1.1.28, linked with 10128

感谢Perl专家Sundeep的一条有用评论,您可以看到可以使用xmlstarlet应用操作的路径列表

$ xmlstarlet el input.xml
NikuDataBus
NikuDataBus/Header
NikuDataBus/LookupQuery
NikuDataBus/LookupQuery/Filter

我完全同意Inian所说的一切,但您也应该注意,您的正则表达式是不正确的:您的示例数据不包含字符串<Filter>。因此,您需要使用不同的模式,例如:

sed '/<Filter/,/</Filter>/s/test/lookup/' ...

但是,再说一遍,你不应该。

最新更新