I’ve recently been spending time programming again. This has been a welcome return to my roots, and it’s certainly reminded me of the pleasure that comes from building good code. Of course, every pleasure has its obverse, and I was reminded of that today because I spent all day beating my head against what appeared to be a bug in NSXMLNode. You’re supposed to be able to use the nodesForXPath: method to do an XPath query against an XML tree. I’d written some code that sent an Autodiscover request to Exchange and parsed the returned data (which looks like this), but my code never found any EwsUrl nodes, even though they were plainly visible.
I tried the xpath command-line tool, and it did what I expected; “xpath ~/Desktop/EWS.xml //EwsUrl” returned both nodes. Apple’s own XMLBrowser sample (in /Developer/Examples/Foundation/XMLBrowser) didn’t work properly either, but the XMLMate plug-in for TextMate did. I looked carefully at the Autodiscover sample in the Exchange 2007 SP1 SDK and found that everything looked OK. Then I went back to my main reference for this stuff. On page 780, I finally found the answer in a subtle clue: the book’s sample was using an XPath query that included the namespace! I modified my code to look like this:
NSXMLNode *rSpace = [NSXMLNode namespaceWithName: @”r”
[[adResponse rootElement] addNamespace:rSpace];
NSArray *idList = [responseRoot nodesForXPath:@”//r:EwsUrl” error:&err];
That solved the problem. So, lesson learned: always make sure that you’ve registered the correct namespace when using nodesForXPath!