Reputation: 21
I have XML file something like this
<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>
I need to update the version attribute if the ID matches with particular set of IDs (I have stored all the required IDs in an array). Array has ID's like
pci_express_1/topics/pci_express_extended_configuration_space.xml
pci_express_1/images/b2ac21.svg
I need Output which looks like
<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>
Please help!! I am new in Perl.
Upvotes: 1
Views: 82
Reputation: 53478
What you need to do this is something like this:
#!/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>
DATA
for illustration, because I have had to mock up some XML similar to yours. You probably shouldn't). And then we print the XML.
You may find set_pretty_print
to be useful for formatting.
E.g.:
$twig -> set_pretty_print('indented_a');
Edit: Given you have included some array content - that doesn't precisely match your attribute, so you need to do it slightly differently:
#!/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>
We build a search regex $search
out of the patterns you have. Then we iterate your child
nodes of your root
(if your XML is bigger, then you might need to use get_xpath
still).
Upvotes: 2