2015-11-19 56 views
0

我想替換特定值(不適用於所有元素)。 這裏所有的都具有相同的Background_color,但我不想只替換特定的Background_color。我們如何執行? 。 這僅僅是一個示例代碼(我會在皮膚的文件名列表,我不應該取代BACKGROUND_COLOR)用unix替換xml中的特定標籤

  <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> 
+0

我想遍歷整個xml文件。 –

+1

到目前爲止您嘗試過什麼? – mkHun

+0

雖然我通常熱衷於嘗試自己做這件事的人,但是當涉及到XML時,它通常會向完全錯誤的方向發展,並試圖用正則表達式來破解它。 – Sobrique

回答

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中att方法::嫩枝讀屬性。儘管如此,我覺得xpath在這個例子中更清晰。

(你也可以做一個更復雜的xpath語句來匹配兒童/兄弟姐妹,但我不確定這會有助於可讀性)。

+0

其實這就是我們的XML文件想要的,(我們正在使用這個爲我們的移動應用程序)。它只是減少了att標籤的數量。 xml文件是一個文件,另一個文件是具有某些特定外觀名稱的名稱。那麼,如何將這個名稱作爲另一個文件並比較這個名稱是否是循環中的一個? –

+0

這是一個完全不同的問題,你應該單獨提出。但是請仔細檢查一下,如果你的XML在源代碼示例中是有效的 - 因爲你引用的內容不是。 – Sobrique

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:新的背景顏色
+0

...但你真的不應該這樣做,因爲基於正則表達式的XML解析是一個骯髒的習慣。 – Sobrique

相關問題