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 (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to