I have a simple xml file that looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<microplateDoc xmlns="http://moleculardevices.com/microplateML">
<camelids>
<species name="Camelus bactrianus">
<common-name>Bactrian Camel</common-name>
<physical-characteristics>
<mass>450 to 500 kg.</mass>
<appearance>
Blah blah blah
</appearance>
</physical-characteristics>
</species>
</camelids>
</microplateDoc>
I'm trying to read the species names with the following perl script:
use XML::LibXML;
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file('/Users/johncumbers/Documents/7_Scripts/Perl/XML_to_MySQL/simplified_camelids.xml');
my $xc = XML::LibXML::XPathContext->new( $doc->documentElement() );
$xc->registerNs('ns', 'http://moleculardevices.com/microplateML');
#loop through to find species nodes
my @n = $xc->findnodes('*/species'); #was */species
foreach $nod (@n) {
print "A: ".$nod->getAttribute("name")."\n";
my @c = $nod->findnodes('./common-name');
}
But I am failing to get find any nodes. Are you able to help and tell me why it is not working please? What is the best website to look up perl functions so that I can try and trouble shoot this myself? How can I get the script to tell me what it is doing, as the output at the moment is just nothing. Many thanks.
You've associated a namespace prefix with the document, but your XPath syntax doesn't use it.
my @n = $xc->findnodes('//ns:species');
should do the job.
Without the prefix you'll not match. Also the */species
path will only match children in the current context (i.e. the top level of the document). Using //species
will find all species
elements in the document. If that doesn't work for you (because the element appears in some other context in the document you don't want to match) use
/*/*/ns:species
as the element is a 'great grandchild' of the top level.
One more XPath reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With