tags:

views:

269

answers:

1

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"&gt;
<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.

+3  A: 

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.

martin clayton
/ns:microplateDoc/ns:camelids/ns:species would work too btw...
martin clayton