在xml文件中查找/替换名称/值对

时间:2014-04-02 19:04:06

标签: xml bash replace xmlstarlet name-value

我试图编写一个shell脚本,它将输入一组名称/值对和一个XML文件作为输入。

目的是在XML文件中搜索" name"来自名称/值对文件的字符串(用标签划分),并替换"值"在XML文件的同一级别定义的字符串(用标签划分)。

e.g。

名称/值对文件

trousers=blue
hat=red
shoes=brown

输入XML文件

<application>
    <Pairs>
        <Pair>
            <name>trousers</name>
            <value>black</value>
        </Pair>
        <IrritatingExtraLayer>
            <Pair>
                <name>hat</name>
                <value>green</value>
            </Pair>
        </IrritatingExtraLayer>
        <Pair>
            <name>shirt</name>
            <value>orange</value>
        </Pair>
    </Pairs>
</application>

预期的输出文件

<application>
    <Pairs>
        <Pair>
            <name>trousers</name>
            <value>blue</value>
        </Pair>
        <IrritatingExtraLayer>
            <Pair>
                <name>hat</name>
                <value>red</value>
            </Pair>
        </IrritatingExtraLayer>
        <Pair>
            <name>shirt</name>
            <value>orange</value>
        </Pair>
    </Pairs>
</application>

我已经创建了一个可以使用xmlstarlet执行此操作的脚本,但它非常慢(我使用的文件长达数千行)。我的脚本中的主代码片段(忽略预处理和后处理)是:

for line in ${namevaluepairs}; do
                name=$(echo ${line} | cut -d'=' -f1)
                value=$(echo ${line} | cut -d'=' -f2)

                outputxml=$(echo ${outputxml} | xmlstarlet ed -u "//Pair/[name='${name}']/value" -v "${value}" )
done

我可以做些什么来改善这个?

1 个答案:

答案 0 :(得分:1)

我通常使用xsh来完成类似的任务。我会对以下与xmlstarlet相比有多快感兴趣。

perl { 
    open $FH, '<', 'namevalues' or die $!;
    while (<$FH>) {
        chomp;
        ($n, $v) = split /=/;
        $h->{$n} = $v;
    }
} ;
open 1.xml ;
for //name {
    $v = xsh:lookup('h', text()) ;
    if $v set ../value $v ;
}
save :b ;

诀窍是将名称 - 值对存储在散列(map,dictionary)中,然后处理所有名称并从散列中检索相应的值。