| Issue 4: | XPath & Default Namespaces | |
| 5 people starred this issue and may be notified of changes. | Back to list |
There is a difference between the behavior of TouchXML and NSXML, in that NSXML cheats with default namespaces. Here is a sample XML that demonstarates the problem: <?xml version="1.0" encoding="UTF-8"?> <FindItemsResponse xmlns="urn:ebay:apis:eBLBaseComponents"> <Timestamp>2008-03-26T23:23:13.175Z</Timestamp> </FindItemsResponse> The following returns an empty array of nodes: CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithXMLString:theXML options:0 error:&theError] autorelease]; NSArray *theNodes = [theXMLDocument nodesForXPath:@"//Timestamp" error:&theError]; Jon has implemented a workaround in the CXMLNode_XPathExtensions class. The following returns the Timestamp node NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: @"urn:ebay:apis:eBLBaseComponents", @"ebay", nil]; CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithXMLString:theXML options:0 error:&theError] autorelease]; NSArray *theNodes = [theXMLDocument nodesForXPath:@"//ebay:Timestamp" namespaceMappings:dict error:&theError];
Apr 4, 2008
Project Member
#1
jwight
Labels:
Has-Workaround
Apr 5, 2008
I've got this working with a default namespace, but I'm having trouble figuring out the syntax for relative paths-- those starting with "./". For example, with my XML document, I can look up "track" nodes with: NSArray *trackNodes; NSDictionary *namespaceMappings = [NSDictionary dictionaryWithObjectsAndKeys:@"http://xspf.org/ns/0/", @"seeqpod", nil]; trackNodes = [rootElementC nodesForXPath:@"//seeqpod:track" namespaceMappings:namespaceMappings error:&error]; But each track node has a child named "location". With NSXML I can grab that with: for (NSXMLNode *currentTrack in trackNodes) { NSArray *locationNodes = [currentTrack nodesForXPath:@"./location" error:&error]; ... } With TouchXML, I tried it this way and get zero hits: for (CXMLNode *currentTrack in trackNodes) { NSArray *locationNodes = [currentTrack nodesForXPath:@"./seeqpod:location" namespaceMappings:namespaceMappings error:&error]; ... } I tried a number of variations on the path-- "seeqpod:./location", "seeqpod:./seeqpod:location", etc. Is this another case of NSXML abusing the XPath spec, or have I just not found the magic cookie?
Apr 5, 2008
Hey Tom, Can you mail me the XML you're using? It could well be a bug. We need to write a lot more unit tests for the xpath methods.
Apr 7, 2008
Fix made for Tom's issue in ticket #9
Labels:
TouchXML
Jul 12, 2008
Is there a way to make it so that I don't have to use /namespacename:etc for xpath? The XML I'm getting from an API has a root element with xmlns="urn:foo:bar" or similar... however, none of the elements are used with namespace:elementname.
Jul 21, 2008
@jtbandes, Yeah check the documention for xpath in libxml2. Closing this bug for now. If you have any specific issues please file a new bug. Thanks.
Status:
Fixed
Jan 10, 2009
I found a small problem and wondering whether it is a bug in my code. When the XML
file has multiple elements repeating, retrieve the nth element, and trying to access
just one attribute in an element using nodesforXPath, results in all elements being
returned. The code is as follows:
NSError *error;
CXMLNode *n;
NSArray *array;
n = [array objectAtIndex:num];
NSString *item = [NSString stringWithFormat:@"//nameSpaceKey:%@", xp];
NSArray *nodes = [n nodesForXPath:item namespaceMappings:nameSpace error:&error];
if (!nodes) {
NSLog(@"stringForPath nodes nil\n");
return nil;
}
NSLog(@"Node %@ ---------", nodes);
array is initialized outside and i am just showing here for an example. "n" retrieves
one element from the doc array. There are n such elements. Within one element, a
specific attribute is being accessed. nodes seems to contain the attribute of all the
elements where as i want just for one element. It used to work with
NSXMLDocument/nodesForXPath. Any workarounds or i am missing something ?
Thanks
mohan
|