Artem
Artem

Reputation: 549

Perl: Get value from XML

I need to get value from this xml - http://pastebin.com/wkh7trd4. Here is my code, but it return nothing:

my $xml = XML::LibXML->new('clean_namespaces' => 1)->parse_file("$tmp_dir/xml/$xml_file_name");
my $xc = XML::LibXML::XPathContext->new($xml);
my $val = $xc->findvalue('/ns2:export/ns2:bankGuarantee/docPublishDate');
print $val;

Upvotes: 1

Views: 115

Answers (3)

Borodin
Borodin

Reputation: 126722

Just creating an XML::LibXML:XPathContext object won't make any difference, you also need to register all the namespaces that you want to use in your XPath expressions. In this case you've used the ns2 namespace without registering any namespaces at all

Your code should look something like this

my $xml = XML::LibXML->new->parse_file("$tmp_dir/xml/$xml_file_name");

my $xc = XML::LibXML::XPathContext->new($xml);
$xc->RegisterNs( ns2 => 'http://example.com/ns2/uri/address');

my $val = $xc->findvalue('/ns2:export/ns2:bankGuarantee/docPublishDate');
print $val;

Note that the URI you register has to match the one in the

xmlns:ns2="http://example.com/ns2/uri/address"

attribute in the data

I'm wondering if the clean_namespaces parser option is your attempt to fix this? clean_namespaces will only remove redundant namespaces, i.e. those that aren't used anywhere in the XML document. There's little point in doing that as you stand little chance of the namespaces clashing, and the time and memory saved will be negligible

Upvotes: 0

Chris Doyle
Chris Doyle

Reputation: 11968

Looks like it has to do with default name space. Not sure how xpath works but @miller seemed to answer his own question here: XML::LibXML, namespaces and findvalue

You can try the below which should hopefully resolve your issue

use strict;
use warnings;
use XML::LibXML;

open(my $xml_file, '<', "xml_to_parse.xml");
my $xml = new XML::LibXML->load_xml(IO => $xml_file);
print $xml->findvalue('/ns2:export/ns2:bankGuarantee/*[local-name()="docPublishDate"]'), "\n";

Upvotes: 1

steve
steve

Reputation: 290

libraries often throw exceptions on failure, if you do not catch them, they could fail silently.

try:

use strict;
use warnings FATAL => 'all';

eval
{
    my $xml = XML::LibXML->new('clean_namespaces' => 1)->parse_file("$tmp_dir/xml/$xml_file_name");
    my $xc = XML::LibXML::XPathContext->new($xml);
    my $val = $xc->findvalue('/ns2:export/ns2:bankGuarantee/docPublishDate');
    print $val;
}
if($@)
{
    print "ERROR: " . $@;
}

If one is failing, it should give you an error.

Upvotes: 0

Related Questions