Regex 在XML文件中,如何使用perl根据另一个属性的模式匹配替换一个属性?

Regex 在XML文件中,如何使用perl根据另一个属性的模式匹配替换一个属性?,regex,xml,perl,libxml2,Regex,Xml,Perl,Libxml2,我有这样的XML文件 <staticResources><staticMMOResource language="eng" variant="default" version="5" id="../../../shared_ip/pex/pex_shared/images/compatible_config_header-type_1_non_cust.svg"> </staticMMOResource> </staticXMLR

我有这样的XML文件

    <staticResources><staticMMOResource language="eng" variant="default" version="5" id="../../../shared_ip/pex/pex_shared/images/compatible_config_header-type_1_non_cust.svg">
</staticMMOResource>
        </staticXMLResource><staticXMLResource language="eng" variant="default" version="9" id="../../../shared_ip/pex/pci_express_1/topics/pci_express_extended_configuration_space.xml">
    </staticXMLResource><staticMMOResource language="eng" variant="default" version="3" id="../../../shared_ip/pex/pci_express_1/images/b2ac21.svg></staticMMOResource></staticResources>
我需要的输出看起来像

<staticResources><staticMMOResource language="eng" variant="default" version="5" id="../../../shared_ip/pex/pex_shared/images/compatible_config_header-type_1_non_cust.svg">
    </staticMMOResource>
            </staticXMLResource><staticXMLResource language="eng" variant="default" version="11" id="../../../shared_ip/pex/pci_express_1/topics/pci_express_extended_configuration_space.xml">
        </staticXMLResource><staticMMOResource language="eng" variant="default" version="5" id="../../../shared_ip/pex/pci_express_1/images/b2ac21.svg></staticMMOResource></staticResources>


您需要这样做:

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig;

my @ids = ( "../../../shared_ip/pex/pci_express_1/topics/pci_express_extended_configuration_space.xml" );

my $twig = XML::Twig -> parse ( \*DATA ); 
foreach my $id ( @ids ) { 
   foreach my $match ( $twig -> findnodes("staticXMLResource[\@id=\"$id\"]") ) {
       $match -> set_att('version', $match->att('version') + 1 );
   }
}
$twig -> print;

__DATA__
<XML>
<staticXMLResource language="eng" variant="default" version="9" id="../../../shared_ip/pex/pci_express_1/topics/pci_express_extended_configuration_space.xml">
</staticXMLResource>
</XML>
编辑:考虑到您包含了一些数组内容-这些内容与您的属性不完全匹配,因此您需要稍微改变一下:

#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig;

my @ids = qw ( pci_express_1/topics/pci_express_extended_configuration_space.xml 
        pci_express_1/images/b2ac21.svg );

#assemble a regex from the search elements. 
my $search = join ( "|", @ids ); 
   $search = qr/($search)/; 

#parse XML - you'll probably want "parsefile" or "parse" depending on your 
#XML source. 
my $twig = XML::Twig -> parse ( \*DATA ); 

#iterate the children of the root (staticResources) node 
# NB - this might not match your larger file. 
foreach my $resource ( $twig -> root -> children ) {
   #test if the 'id' attribute matches our regex. 
   #note - regex is unanchored, so substring matches work. 
   if ( $resource -> att('id') =~ m/$search/ ) { 
      #increment version id. 
      $resource -> set_att('version', $resource->att('version') + 1 ); 
   }
}
#set output format
$twig -> set_pretty_print('indented_a'); 
#print to stdout. 
#To print to a file, you may want print {$opened_fh} $twig -> sprint; 
$twig -> print; 

__DATA__
<staticResources>
<staticXMLResource language="eng" variant="default" version="9" id="../../../shared_ip/pex/pci_express_1/topics/pci_express_extended_configuration_space.xml">
    </staticXMLResource>
    <staticXMLResource language="eng" variant="default" version="9" id="../../../shared_ip/pex/pci_express_1/topics/pci_express_extended_configuration_space.xml">
</staticXMLResource>
<staticMMOResource language="eng" variant="default" version="3" id="../../../shared_ip/pex/pci_express_1/images/b2ac21.svg"></staticMMOResource>
</staticResources>
#/usr/bin/env perl
严格使用;
使用警告;
使用XML::Twig;
my@ids=qw(pci_express_1/topics/pci_express_extended_configuration_space.xml
pci_express_1/images/b2ac21.svg);
#从搜索元素组装正则表达式。
我的$search=join(“|”,@ids);
$search=qr/($search)/;
#解析XML—您可能需要“解析文件”或“解析”,具体取决于您的
#XML源代码。
my$twig=XML::twig->parse(\*数据);
#迭代根(staticResources)节点的子节点
#注意-这可能与较大的文件不匹配。
foreach my$资源($twig->root->children){
#测试“id”属性是否与正则表达式匹配。
#注意-regex是未编排的,因此子字符串与工作匹配。
如果($resource->att('id')=~m/$search/){
#增量版本id。
$resource->set_att('version'),$resource->att('version')+1;
}
}
#设置输出格式
$twig->set_pretty_print('indented_a');
#打印到标准输出。
#要打印到文件,您可能需要打印{$opened\u fh}$twig->sprint;
$twig->print;
__资料__

我们根据您已有的模式构建一个search regex
$search
。然后,我们迭代
根节点的
子节点
(如果XML更大,那么可能仍然需要使用
获取xpath

初始样品将帮助我们帮助您。比如-你的阵列中有什么?一个较长(且有效)的XML片段也是如此。这与您的
id
元素不匹配。@Sobrique我已经编辑了这个问题。。请在相应的编辑后再次查看。输入的XML仍然无效。请-如果您引用的是子集,至少要通过验证器运行它。
$twig -> set_pretty_print('indented_a');
#!/usr/bin/env perl
use strict;
use warnings;

use XML::Twig;

my @ids = qw ( pci_express_1/topics/pci_express_extended_configuration_space.xml 
        pci_express_1/images/b2ac21.svg );

#assemble a regex from the search elements. 
my $search = join ( "|", @ids ); 
   $search = qr/($search)/; 

#parse XML - you'll probably want "parsefile" or "parse" depending on your 
#XML source. 
my $twig = XML::Twig -> parse ( \*DATA ); 

#iterate the children of the root (staticResources) node 
# NB - this might not match your larger file. 
foreach my $resource ( $twig -> root -> children ) {
   #test if the 'id' attribute matches our regex. 
   #note - regex is unanchored, so substring matches work. 
   if ( $resource -> att('id') =~ m/$search/ ) { 
      #increment version id. 
      $resource -> set_att('version', $resource->att('version') + 1 ); 
   }
}
#set output format
$twig -> set_pretty_print('indented_a'); 
#print to stdout. 
#To print to a file, you may want print {$opened_fh} $twig -> sprint; 
$twig -> print; 

__DATA__
<staticResources>
<staticXMLResource language="eng" variant="default" version="9" id="../../../shared_ip/pex/pci_express_1/topics/pci_express_extended_configuration_space.xml">
    </staticXMLResource>
    <staticXMLResource language="eng" variant="default" version="9" id="../../../shared_ip/pex/pci_express_1/topics/pci_express_extended_configuration_space.xml">
</staticXMLResource>
<staticMMOResource language="eng" variant="default" version="3" id="../../../shared_ip/pex/pci_express_1/images/b2ac21.svg"></staticMMOResource>
</staticResources>