在 unix 中替换 xml 中的特定标签
Replace specific tags in xml in 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>
假设您的 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 -> children()
迭代att
元素,XML::Twig中的att
方法读取属性。不过,我觉得 xpath
在这个例子中更清楚。
(您也可以做一个更复杂的 xpath 语句来匹配 children/siblings,但我不确定这是否有助于提高可读性)。
在 awk 中,你可以试试这个
awk -F"=?\"?[ ]*" 'BEGIN{replace="sknLblG3S3"; newcolor="0,0,0"}
=="Name"{name=}
(=="Background_color" && match(replace, name))
{gsub(/value="[0-9,]*"/, "value=\""newcolor"\"");}
{print;}' inputFile
您必须在 BEGIN
块中定义两个变量:
replace
:要替换的皮肤名称,例如replace="name,sknLblG3S3"
newcolor
: 新的背景颜色
我想替换特定值(不是所有元素)。 这里所有人都有相同的 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 解析器。当你标记 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 -> children()
迭代att
元素,XML::Twig中的att
方法读取属性。不过,我觉得 xpath
在这个例子中更清楚。
(您也可以做一个更复杂的 xpath 语句来匹配 children/siblings,但我不确定这是否有助于提高可读性)。
在 awk 中,你可以试试这个
awk -F"=?\"?[ ]*" 'BEGIN{replace="sknLblG3S3"; newcolor="0,0,0"}
=="Name"{name=}
(=="Background_color" && match(replace, name))
{gsub(/value="[0-9,]*"/, "value=\""newcolor"\"");}
{print;}' inputFile
您必须在 BEGIN
块中定义两个变量:
replace
:要替换的皮肤名称,例如replace="name,sknLblG3S3"
newcolor
: 新的背景颜色