Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re: nodelists and nodesets

by erroneousBollock (Curate)
on Nov 23, 2007 at 03:33 UTC ( [id://652485]=note: print w/replies, xml ) Need Help??


in reply to nodelists and nodesets

What I'm doing is getting a nodeset using find(), for example:

my $xp = XML::XPath->new(filename => $file); $plantdata->{nodeset} = $xp->find('//loop_device[@loop_number="1"]');
Which returns an XML::XPath::NodeSet.

Calling $plantdata->{nodeset}->get_nodelist() will return a list of XML::Node (and/or descendant) objects.

What I've done is go back to the beginning like this:

if ($devicetype eq "complex") { $seachstring = sprintf "//loop_device[@devicename=\"%s\"]/subdevice" +, $devicename; $subdevice = $xp->find($searchstring); }
That's unnecessary, using $device (which in your case is an XML::XPath::Node object returned from $nodeset->get_nodelist())as the context is fine.

I'm doing this because $device is a node from a node list not from a nodeset so I can't do this:

$subdevice = $device->find('/subdevice');
Yes, you can :-). The synopsis in the XML::XPath::NodeSet documentation shows that usage pattern.

I don't know the structure of your XML (you've not provided a sample), but that is exactly how this sort of this is usually done.

If I go into the debugger and look at $plantdata->{nodeset} and $device both seem to contain a hell of a lot more than just the node I want. Is there a way to turn a $device node back into a nodeset so that I can dig deeper into it rather than going back to $xp and starting again?
Now, why would you use a debugger to look in the XML::XPath::Node object? ;)

Actually, every node object returned from the initial XPath context has a references back to the main XPath context's XML DOM. That's likely what you're seeing in the debugger.

XML::XPath::Node objects must have the full context, otherwise you couldn't perform XPath queries like

  $node->find('/foo/../../../bar[2]');

because the context wouldn't be there to traverse!

The moral of the story is to use DOM methods to traverse the XML DOM, not a debugger.

-David

Replies are listed 'Best First'.
Re^2: nodelists and nodesets
by nonnonymousnonk (Novice) on Nov 23, 2007 at 12:16 UTC
    Thanks David,

    That's unnecessary, using $device (.....) as the context is fine.

    'Context' is the magic word that made the penny drop. This:

    $subdevice = $device->find('/subdevice', $device);
    Does just what I need.

    I was only looking at stuff in the debugger to try to understand the difference between nodesets and node lists. It wasn't helpful as both are far too large to read.
    All I could really gleen was whether my code was giving vaguely sensible results.

    Thanks a mill
    Nonk

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://652485]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (3)
As of 2024-04-16 06:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found