Re: Traversing an NSXML subtree
Re: Traversing an NSXML subtree
- Subject: Re: Traversing an NSXML subtree
- From: Graham Cox <email@hidden>
- Date: Fri, 29 May 2009 00:21:45 +1000
On 28/05/2009, at 11:56 PM, McLaughlin, Michael P. wrote:
Hello,
I think you’re correct in what you show below. I was expecting
that, since an XML document is already a tree, it would already have
an equivalent to what you describe. I’ve reinvented the wheel too
many times and now try to avoid it when possible.
An earlier responder suggested using Xpath and, right now, I’m
looking to see if that might be easier. At first, it seemed like
overkill but perhaps not in my case.
Hi,
Seriously? This is about as easy as I've seen tree traversal get, not
sure how it could be any easier. Though see below, it's even easier ;-)
Your original post states:
In reviewing the NSXML documents, I found no really simple way to
traverse a
subtree of an NSXMLDocument. That is, traverse from the root until
you hit
the node with the right name then pretend that that node is the root
of a
smaller tree and traverse just the latter. [Everything I found
talked only
about sibs and (immediate) children, not grandchildren, etc.]
Since this is such a common thing to do, I'm guessing that I must have
misread the docs somehow.
Could someone clue me in as to the preferred method to do a
subtraversal?
Obviously my -traversal method doesn't do anything, but it can
trivially solve the first part - find the node with a given name. It
just traverses until it gets a match. At that point your requirements
are a bit vague. You say "traverse that node as if it were the root of
a smaller tree". Well, it is. So just do what you have to do.
If the NSXMLMode class doesn't have the exact method you need, just
add what you need to it in a category, as I showed with -traverse. But
really, since the children of a node is an array object, its easy to
iterate. I'm not sure what more you would expect? If you want to pass
each child node an object (visitor pattern, say) then [NSArray
makeObjectPerformSelector:withObject:] reduces it to one line. If the
method in question is one of your category methods you can place this
inside it and boom - one line of code will visit all subnodes and send
them a specific additional object. You can do anything you want. In
one line.
@implementation NSXMLNode (Visitor)
- (void) visitSubnodesWithObject:(id) visitor
{
// do something useful with the visitor if necessary
[visitor doSomethingWithNode:self];
// visit all subnodes
[[self children] makeObjectPerformSelector:_cmd
withObject:visitor]; // _cmd is equivalent to @selector(<this method>)
}
@end
Invoke as -[NSXMLDocument visitSubnodesWithObject:foo]; // will visit
all subnodes and hand each one to <foo>. The visitor can then do what
it needs to do, including ignoring the node altogether if it's not of
interest.
--Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden