使用xmlstarlet替换XML中的标签值

时间:2018-08-02 06:36:23

标签: xml shell sed xmlstarlet

我正在尝试用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>

2 个答案:

答案 0 :(得分:4)

使用XML这样的非语法感知工具来解析sed是一个坏主意。如果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

答案 1 :(得分:1)

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

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

但是,同样,你不应该。