I\'m trying to parse an XML manifest file for an Articulate eLearning course (imsmanifest.xml).
An excerpt of the XML structure is provided below (I\'m trying to drill d
You're asking to locate elements named manifest
in the null namespace, but you want elements named manifest
in the http://www.imsproject.org/xsd/imscp_rootv1p1p2
namespace.
Fixes:
use strict;
use warnings;
use XML::LibXML qw( );
use XML::LibXML::XPathContext qw( );
my $xml_qfn = 'imsmanifest.xml';
my $parser = XML::LibXML->new( no_network => 1 );
my $doc = $parser->parse_file($xml_qfn);
my $xpc = XML::LibXML::XPathContext->new();
$xpc->registerNs( a => "http://www.adlnet.org/xsd/adlcp_rootv1p2" );
$xpc->registerNs( i => "http://www.imsproject.org/xsd/imscp_rootv1p1p2" );
for my $item ($xpc->findnodes('/i:manifest/i:organizations/i:organization/i:item', $doc)) {
my $title = $xpc->find('i:title/text()', $item);
my $mastery = $xpc->find('a:masteryscore/text()', $item);
print "$title: $mastery\n";
}
Note: The actual choice of prefix for use in an XPaths (a
and i
) is arbitrary. You can pick whatever you want, just like when you compose an XML document.
Note: I added no_network => 1
to prevent libxml from fetching the DTDs every time you parse the XML doc.