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

XML::XPath is misbehaving (or else I just don't get it)..

my $tree = get_xml_as_tree($url) # get_xml_as_tree is a method that #builds an xml::xpath tree, from the $url source and we know it works. #used it successfully elsewhere.. foreach my $node ($tree->findnodes('path'){ if ($node->exists('path')){ #do some stuff } }

throws up an error

No such method exists in XML::XPath::Node::ElementImpl

at the line if ($node->exists('path'))

now, there is a method exists($path,$context) in XML::XPath, why would i get this error? what am i missing? monks, please illuminate!

Replies are listed 'Best First'.
Re: XML::XPath Question
by Corion (Patriarch) on Nov 10, 2010 at 20:12 UTC

    ->findnodes() returns an XML::XPath::NodeSet, not a (Perl) list of nodes.

    See ->get_nodelist of that object.

      That's not what the docs say, and that's not what the error message says. (It mentions "Node", not "NodeSet".)

      The error message is actually spot on. The OP is trying to call the "exists" method of a node, but nodes don't have an "exists" method. The correct usage is

      $tree->exists('path', $node)

        I was looking at <a href="http://search.cpan.org/~msergeant/XML-XPath-1.13/XPath.pm#findnodes%28$path,_$context%29">->findnodes, and there it says that.

        But I remember hours of staring at various parts of the documentation, trying to piece together a whole, so there might be other parts that say something else.

        I'm sorry, but I don't get it, but a node is a tree, and vice-versa.. what is the distinction?

      Actually, another question.. the doc says that findnodes

      "Returns a list of nodes found by $path, optionally in context $context. In scalar context returns an XML::XPath::NodeSet object."

      I had taken that to mean that since I am invoking the method inside the braces for a foreach loop

      foreach my $node ($tree->findnodes())

      It would return a list of nodes.. Isn't that a list contest? Why would it be a scalar context?

        Indeed, it should return the list of nodes in your case. I think I was just barking up the wrong tree, sorry.

      thats what i thought too, and tried these changes:

      foreach my $node($tree->findnodes('path')->get_nodelist(){ if ($node->exists('path')){

      and alternatively

      my $node_list = $tree->find('path'); foreach my $node($node_list->get_nodelist()){ if ($node->exists('path')){

      I still get the same error..

Re: XML::XPath Question
by Anonymous Monk on Nov 11, 2010 at 03:29 UTC

    perl allows you to create objects, and then you can define methods which those objects can call. XML::XPath is just some programmer's module that you can use to create XML::Xpath objects and call methods on those objects. exists() is one of those methods. It says so in the documentation.

    But just because one perl programmer creates a module that defines a method does not mean that all perl objects can call that method. Objects can only call methods that were specifically defined for that object(or that they inherit from parent objects). XML::XPath::Node objects and XML::XPath objects are not the same thing.

    Read ikegami's post again.

Re: XML::XPath Question
by Anonymous Monk on Nov 11, 2010 at 03:25 UTC

    perl allows you to create objects, and then you can define methods which those objects can call. XML::XPath is just some programmer's module that you can use to create XML::Xpath objects and call methods on those objects. exists() is one of those methods. It says so in the documentation.

    But just because one perl programmer creates a module that defines a method does not mean that all perl objects can call that method. Objects can only call methods that were specifically defined for that object(or that they inherit from parent objects). XML::Node objects and XML::XPath objects are not the same thing.

    Read ikegami's post again.

Re: XML::XPath Question
by Anonymous Monk on Nov 11, 2010 at 03:30 UTC
    nm
Re: XML::XPath Question
by Anonymous Monk on Nov 11, 2010 at 03:35 UTC
    Whoops. Scratch those previous posts. I think XML::XPath must be a parent class of XML::XPath::Node based on the name, (but I don't think that is necessarily a requirment in perl), so it should inherit the exists() method. The error message you posted says something about an XML::XPath::Node::ElementImpl, which I don't see in the documentation.
Re: XML::XPath Question
by aquarium (Curate) on Nov 10, 2010 at 23:56 UTC
    is 'path' an actual xml node in your input..or is it a value you haven't yet properly specified. or is this merely semi-pseudocode to illustrate a point?
    the hardest line to type correctly is: stty erase ^H