foreach my $child ($obj->children()) { next unless $child->name eq 'paragraph'; # code goes here }
More complex cases involve needing to operate on a subset of children defined by two or more levels of containership. For example, to collect all the headers on all the pages:
foreach my $child ($obj->children()) { next unless $child->name eq 'page'; foreach my $grandchild ($child->children()) { next unless $grandchild->name eq 'header'; # code goes here } }
Suddenly it occurred to me that I've seen patterns like this before, in code dealing with XML. And I've seen a good solution to the problem, XPath, which I've never really gotten a good chance to use. So, today I added a method to do XPath-style matching called match(). It only supports the simplest patterns, but I plan to improve it incrementally.
For example, the first block of code can be translated to:
foreach my $para ($obj->match('paragraph')) { # code goes here }
That's no big deal, but the fun starts translating the second one:
foreach my $header ($obj->match('/page/header')) { # code goes here }
Once I wrote match(), I realized I had another tool I didn't even realize I could use. I now have a way to unqiuely identify a node in a tree. For example, to get the third paragraph on the fourth page:
($para) = $obj->match('/page[3]/paragraph[2]');
So not only is match() a simpler and cleaner interface to selecting nodes from the tree, it also offers an entirely novel feature: unique indentifiers for nodes inside the tree. I added an xpath() method to return this path for a given node. I've already found one area in the application where this significantly reduces code complexity and I expect to find more.
-sam
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: XPath matching for object trees
by tomhukins (Curate) on Feb 11, 2003 at 13:28 UTC | |
Re: XPath matching for object trees
by perrin (Chancellor) on Feb 11, 2003 at 16:12 UTC | |
Re: XPath matching for object trees
by diotalevi (Canon) on Feb 11, 2003 at 15:32 UTC |