My favorites | Sign in
Project Home
READ-ONLY: This project has been archived. For more information see this post.
Search
for
  Advanced search   Search tips   Subscriptions
Issue 4: XPath & Default Namespaces
5 people starred this issue and may be notified of changes. Back to list
Status:  Fixed
Owner:  rick.hoi...@gmail.com
Closed:  Jul 2008


 
Reported by rick.hoi...@gmail.com, Apr 4, 2008
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
Yep. Technically NSXML* is at fault here by not supporting the XPath spec 100%.

But that's moot as we're trying to emulate NSXML* as much as possible. Until we work out how to do that we have 
the alternative API: [NSXMLNode nodesForXPath:namespaceMappings:error:] that allows you to explicitly define 
what namespaces to keep.

THe alternative API will be kept even if we manage to duplication NSXML* functionality.
Labels: Has-Workaround
Apr 5, 2008
#2 atomicb...@gmail.com
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
Project Member #3 jwight
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
Project Member #4 jwight
Fix made for Tom's issue in ticket #9
Labels: TouchXML
Jul 12, 2008
#5 jtban...@gmail.com
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
Project Member #6 jwight
@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
#7 surut...@gmail.com
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


Powered by Google Project Hosting