Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

XPath-like method for searching/editing structures

by nglenn (Beadle)
on Oct 09, 2012 at 20:14 UTC ( #998063=perlquestion: print w/replies, xml ) Need Help??
nglenn has asked for the wisdom of the Perl Monks concerning the following question:

I like the feature in Data::Dive that allows me to assign variables to some place in a hash:
DiveVal( $root, \( qw( num 1 2 ) ) ) = 3;
I'd like to do something even more general than that. I have parsed something with P::RD and have a big tree structure. I want to be able to search for specific structures and edit them using using the same sort of syntax, e.g. providing a path to find in the structure and providing a new value, or perhaps a regex replacement. I guess what I'm thinking of is like XML::Twig's ability to search and replace given a twig to find and a subroutine to execute when it is found. Is there any existing module that can do this?

Replies are listed 'Best First'.
Re: XPath-like method for searching/editing structures
by tobyink (Abbot) on Oct 09, 2012 at 20:40 UTC

    There are a number of modules that offer XPath-like syntax for drilling down into nested Perl data structures. One is my own JSON::Path which implements the JsonPath specification which also has freely available PHP, Javascript and C# (.NET) implementations.

    JSON::Path also has links to various other similar Perl modules that I found in its SEE ALSO section.

    I do like that Data::Diver lvalue feature. I may have to steal that.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
      This basically what I am looking for, except that it only does searching and not editing. If you end up "stealing" the lvalue feature, I'd love to know about it. I'm actually asking quite a bit ahead of time of my needing this functionality.
Re: XPath-like method for searching/editing structures
by ambrus (Abbot) on Oct 09, 2012 at 20:33 UTC

    What you're searching for seems too general to make sense. Could you maybe ask for something more concrete that you really need?

    If you just want to do a regex replacement on a value, Data::Diver doesn't stop you. Just write DiveVal(...) =~ s/foo/bar/;

Re: XPath-like method for searching/editing structures
by Anonymous Monk on Oct 10, 2012 at 07:51 UTC
Re: XPath-like method for searching/editing structures
by sundialsvc4 (Abbot) on Oct 10, 2012 at 13:32 UTC

    As an aside, it can be useful to rig-up a “data walker” object that will iterate through a data-structure ... search for “walker” ... and then perhaps maintain a push-down stack of such objects.   Once, I solved a similar problem by devising a walker that would call a specified sub (coderef ...) when it found a matching node.   Each subroutine in turn made the decisions that needed to be made at that level, and spawned another walker-instance to proceed further.   Thus, the walkers handled the task of navigation while the subroutines made the case-specific decisions.   (It was a lot easier to do than to describe.)   I did it this way because, while I could not predict what the shape and depth of the structure would be, I could describe the logic as a small number of reusable, node-specific cases.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://998063]
Front-paged by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (6)
As of 2017-02-22 16:56 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (332 votes). Check out past polls.