【问题标题】:Replace specific tags in xml in unix在Unix中替换xml中的特定标签
【发布时间】:2016-02-21 02:37:39
【问题描述】:

我想替换特定值(不是所有元素)。 这里所有人都有相同的 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>

【问题讨论】:

  • 我想遍历整个 xml 文件。
  • 到目前为止你尝试了什么?
  • 虽然我通常热衷于尝试自己做的人,但当谈到 XML 时,这通常会朝着完全错误的方向发展,并试图用正则表达式破解它。

标签: xml perl unix awk ed


【解决方案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;

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

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

【讨论】:

  • 实际上这就是我们的 xml 文件想要的,(我们将它用于基于移动的应用程序)。只是我减少了att标签的数量。 xml 文件是一个文件和另一个文件,用于具有某些特定皮肤名称的名称。那么我如何取另一个文件的名称并比较这个名称是否是循环中的名称??
  • 这是一个完全不同的问题,您可能应该单独问。但是请仔细检查您的 XML 在您的源示例中是否有效 - 因为您引用的内容不是。
【解决方案2】:

在 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-block 中定义两个变量:

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

【讨论】:

  • ...但您真的不应该这样做,因为基于正则表达式的 XML 解析是一种肮脏的习惯。
猜你喜欢
  • 1970-01-01
  • 2021-11-29
  • 2015-10-15
  • 2013-07-03
  • 2011-05-18
  • 2012-09-01
  • 2017-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多