Заменить определенные теги в XML в Unix
Я хотел бы заменить конкретные значения (не для всех элементов). Здесь все имеют один и тот же 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 ответа
Предполагая, что ваш 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()
если вам легче читать, а att
Метод в XML::Twig читает атрибуты. я чувствую xpath
более понятен в этом примере.
(Вы также можете сделать более сложный оператор xpath, чтобы сопоставить детей / братьев и сестер, но я не уверен, что это улучшило бы удобочитаемость).
В 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
: Новый цвет фона