在unix中替换xml中的特定标记

时间:2015-11-19 05:07:29

标签: xml perl unix awk ed

我想替换特定值(不适用于所有元素)。  这里所有都有相同的Background_color,但我不想只替换特定的Background_color。我们该如何实施? 这只是一个示例代码。(我会在文件中列出皮肤名称,我不应该替换Background_color)

            <Skins>
             <skin>
               <att name="Name" value="sknLblG3S3" type="String"/>
               <att name="WidgetType" value="Label" type="String"/>
               <att name="Background_color" value="228,221,213" type="RGB"/>
            <skin>
            <skin>
              <att name="Name" value="name" type="String"/>
              <att name="WidgetType" value="Label" type="String"/>
              <att name="Background_color" value="228,221,213" type="RGB"/>
            <skin>
            <skin>
              <att name="Name" value="sknLblG3S5" type="String"/>
              <att name="WidgetType" value="Label" type="String"/>
              <att name="Background_color" value="228,221,213" type="RGB"/>
            <skin>
            <skins>

2 个答案:

答案 0 :(得分:1)

假设您的XML实际上是有效的(您的样本不是 - 我必须手动修复某些标记) - 那么您应该使用XML解析器。当你标记了perl时,我假设perl答案是可以接受的:

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;

my $twig = XML::Twig->parsefile( 'your_file.xml' );

#find and iterate all the 'skin' elements. 
foreach my $skin ( $twig->get_xpath('//skin') ) {
    #Check the 'att' element with these particular attributes. E.g. Name, sknLblG3S3
    if ( $skin->get_xpath('./att[@name="Name"][@value="sknLblG3S3"]') ) {
        #select the att with a name of 'Background_Colour' 
        my $bg_att = $skin->get_xpath( './att[@name="Background_color"]', 0 );
        #modify the attribute 'value'. 
        $bg_att->set_att( 'value', "123,456,789" );
    }
}

#set output formatting - note, this can break with certain XML elements, which you don't seem to have. 
$twig->set_pretty_print('indented');
$twig->print;

如果您觉得更容易阅读,可以使用att迭代$skin -> children()元素,并且XML :: Twig中的att方法读取属性。我觉得xpath在这个例子中更清楚。

(你也可以做一个更复杂的xpath语句来匹配孩子/兄弟姐妹,但我不确定它是否有助于提高可读性)。

答案 1 :(得分:0)

在awk中,你可以试试这个

awk -F"=?\"?[ ]*" 'BEGIN{replace="sknLblG3S3"; newcolor="0,0,0"}
                   $4=="Name"{name=$6}
                   ($4=="Background_color" && match(replace, name))
                      {gsub(/value="[0-9,]*"/, "value=\""newcolor"\"");}
                   {print;}' inputFile

您必须在BEGIN - 块中定义两个变量:

  • replace:要替换的皮肤名称,例如replace="name,sknLblG3S3"
  • newcolor:新的背景颜色