1

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;
Artem
  • 517
  • 1
  • 7
  • 24

3 Answers3

1

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";
Community
  • 1
  • 1
Chris Doyle
  • 10,703
  • 2
  • 23
  • 42
0

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.

steve
  • 290
  • 1
  • 11
0

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

Borodin
  • 126,100
  • 9
  • 70
  • 144