Reputation: 368
I'm currently working on Perl script that will mock node values based on specific criteria. I have similar parents nodes with in a file, out of which on specific criteria I should replace/edit child node value. Given Sample file below. I'm using XML::LibXML
module to do this work for me.
But it seems to be not working as expected, because my below piece of code is always replacing node values from the first found parent node irrespective of the criteria that I'm providing.
Here is my Piece of code that I have tested.
use strict;
use warnings;
use XML::LibXML;
my $parser = XML::LibXML->new;
my $doc = $parser->parse_file("Test.xml");
my $root = $doc->getDocumentElement();
##ERROR KEY ENTRY_MISSING
if ( my $valdExpHBill = $doc -> findnodes('//shipment//Flag[string()="true"]')) {
print "valid flag is true\n";
##ID_MISSING
if (my $buEnShp = $doc -> findnodes ('//shipment//business//Type[string()="Shipper"]')) {
print "Shipper business exist under this shipment\n";
my ($buEnShpGciVal) = $doc->findnodes('//shipment//business//number//text()');
$buEnShpGciVal->setData(' ');
my ($buEnShpBNoVal) = $doc->findnodes('//shipment//business//busNumber//text()');
$buEnShpBNoVal->setData(' ');
my $EDE5 = $doc->toFile("ID_MISSING.xml",1);
}
}
Sample Input File (Test.xml)::
<shipment>
<flag>true</flag>
<business>
<Type>Consignee</Type>
<number>G0213</number>
<busNumber>3006</busNumber>
</business>
<business>
<Type>Shipper</Type>
<number>G0113</number>
<busNumber>3116</busNumber>
</business>
</shipment>
Out Put file (ID_MISSING.xml)::
<shipment>
<flag>true</flag>
<business>
<Type>Consignee</Type>
<number> </number>
<busNumber> </busNumber>
</business>
<business>
<Type>Shipper</Type>
<number>G0113</number>
<busNumber>3116</busNumber>
</business>
</shipment>
Expected output (ID_MISSING.xml)::
<shipment>
<flag>true</flag>
<business>
<Type>Consignee</Type>
<number>G0213</number>
<busNumber>3006</busNumber>
</business>
<business>
<Type>Shipper</Type>
<number> </number>
<busNumber> </busNumber>
</business>
</shipment>
Actually I want to match Shipper parent node and want to replace its child elements with blanks. But always it is matching the first found parent node and replacing/editing those values. I want to achieve this using XML::LibXML
module, even though I can other options using some other XML related modules in Perl.
As per my understanding, even though I'm checking for specific condition, it is just parsing the XML document and getting first found parent node and replacing it's child node values. I just want to understand how exactly I can edit child nodes of specific parent node. Your help is appreciated in this.
Upvotes: 0
Views: 322
Reputation: 241848
If you want to only search in a subtree of a node, call findnodes
as a method of the node, not of the whole document object.
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
use strict;
use warnings;
use XML::LibXML;
my $doc = 'XML::LibXML'->load_xml(location => shift);
my $root = $doc->getDocumentElement;
if ( my $valdExpHBill = $doc -> findnodes('//shipment[flag="true"]')) {
print "valid flag is true\n";
if (my ($buEnShp) = $doc->findnodes('//shipment//business[Type="Shipper"]')) {
print "Shipper business exist under this shipment\n";
my ($buEnShpGciVal) = $buEnShp->findnodes('number/text()');
$buEnShpGciVal->setData(' ');
my ($buEnShpBNoVal) = $buEnShp->findnodes('busNumber/text()');
$buEnShpBNoVal->setData(' ');
my $EDE5 = $doc->toFile("ID_MISSING.xml",1);
}
}
Upvotes: 2