Reputation: 850
I am having some issues using
XML::LibXML
with namespaces. I have parsed files with namespaces before but this one is a bit different because it is defined with xlmns:abc
rather then just xlmns
.
I can't extract the 893
value of abc:id
from this element
<element name='THEFIELD' type='string' abc:id='893' minOccurs='0' maxOccurs='1'>
Sample data
<schema
xmlns:abc="http://www.example.com/schemas/abc"
targetNamespace="http://example.com/schemas/product"
elementFormDefault="qualified">
<TheType name='MyName'>
<sequence>
<element name='THEFIELD' type='string' abc:id='893' minOccurs='0' maxOccurs='1'>
<annotation><documentation>Identifier - Realtime</documentation></annotation>
</element>
My code returns all values correctly (the name
and type
attributes) but not abc:id
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
use XML::LibXML;
use XML::LibXML::XPathContext;
my $filename = '/schema.xml';
my $dom = XML::LibXML->load_xml( location => $filename );
my $xpc = XML::LibXML::XPathContext->new( $dom );
$xpc->registerNs( 'ns', 'abc:http://www.example.com/schemas/abc' );
foreach my $title ( $xpc->findnodes( '//schema' ) ) {
foreach my $title ( $xpc->findnodes( '//TheType[@name="MyName"]/sequence/element' ) ) {
say $title->findvalue( './@name' ), '|', $title->findvalue( '??????' ), '|', $title->findvalue( './@type' );
}
}
My thoughts are
$xpc->registerNs( 'ns', 'abc:http://www.example.com/schemas/abc' );
is wrong
Every possibility I tried for the findvalue
for abc:id
—where the ????
is in the code—was wrong.
I tried many things here including things like ns:/@id
to *[local-name()="id"]
Upvotes: 0
Views: 696
Reputation: 241858
XML::LibXML::XPathContext doesn't have to be used (in the recent years), it's loaded with XML::LibXML.
The correct usage of the registerNs
function is to give it a prefix and URI.
Using the same variable for a nested loop makes no sense, especially if you don't use the outer variable anywhere.
You can use join to avoid repeating the call to findvalue
.
#!/usr/bin/perl
use strict;
use warnings;
use feature qw{ say };
use XML::LibXML;
my $filename = shift;
my $dom = 'XML::LibXML'->load_xml(location => $filename);
my $xpc = 'XML::LibXML::XPathContext'->new($dom);
$xpc->registerNs(abc => 'http://www.example.com/schemas/abc');
for my $title ($xpc->findnodes('//TheType[@name="MyName"]/sequence/element')) {
say join '|', map $title->findvalue($_), '@name', '@abc:id', '@type';
}
Upvotes: 4