BluePerlDev has asked for the wisdom of the Perl Monks concerning the following question:

Greetings, O Wise Monks. I am hopeful that someome here in the Monastary who is better versed in using the XML modules can assist me, as this is my first time dealing with them.

Problem: I am currently using XML::Simple in an automation script that interacts with an XML-based API. However, some of the functionality that I will need to add in next will require a more elegant solution than XML::Simple to manage. I have decided to use XML::LibXML since it allows both DOM and SAX-based functionality. However, when compiling and installing the module, I do not get the Node.pm module, which contains methods like getFirstChild(), to access the data returned by the XML parser. Instead, I get the Nodelist.pm module, and the .pod file for Node.pm.

So my question is, is this a corrupt build of LibXML? Or am I just missing something simple that will build the Node.pm file? Like maybe Node.pm is found in a different XML module?

Since all systems are not created equal, below are the relevant parts of my environment that I'm working with:

Please let me know if you need more information. Any help you can give will be greatly appreciated. Thanks in advance.

Replies are listed 'Best First'.
Re: Missing Node.PM in XML::LibXML v1.69
by almut (Canon) on Jun 11, 2010 at 19:37 UTC
    I do not get the Node.pm module, which contains methods like getFirstChild()

    Do you get an error when you try to use getFirstChild()?  The method is in LibXML.xs:

    SV* firstChild( self ) xmlNodePtr self ALIAS: getFirstChild = 1 CODE: PERL_UNUSED_VAR(ix); RETVAL = PmmNodeToSv( self->children, PmmOWNERPO( PmmPROXYNODE(self) ) ); OUTPUT: RETVAL

    so things should be fine (there mustn't necessarily be a Node.pm file for the method to work).

      I do. I get

      Can't locate object method "getFirstChild" via package "XML::LibXML::NodeList"

      from my test script.

        XML::LibXML::NodeList isn't XML::LibXML::Node.

        You are probably using findnodes in scalar context.

        my @nodes = $doc->findnodes(...); # Return all matching nodes my $nodes = $doc->findnodes(...); # Ditto, as a NodeList

        If you want the first match node, call findnodes in list context.

        my ($node) = $doc->findnodes(...); # Get first matching node.

        If you want to visit every matching node, the following is probably more what you want:

        for my $node ($doc->findnodes(...)) { ... }

        You're presumably calling it on the wrong object type.  What does your code/xml look like?

        Here's a simple example using getFirstChild that works:

        #!/usr/bin/perl use strict; use warnings; use XML::LibXML; my $parser = XML::LibXML->new(); my $doc = $parser->parse_fh(\*DATA); for my $elem ( $doc->getElementsByTagName('foo') ) { my $val = $elem->getFirstChild()->nodeValue(); print "$val\n"; # Foo1 Foo2 } __DATA__ <?xml version = "1.0" encoding="UTF-8" ?> <doc> <foo>Foo1<bar>Bar</bar></foo> <foo>Foo2</foo> </doc>
Re: Missing Node.PM in XML::LibXML v1.69
by Khen1950fx (Canon) on Jun 12, 2010 at 01:31 UTC
    Node.pod is an abstract base class used by other XML::LibXML nodes. It's not a module, rather part of the documentation.