zzycami / touchcode

Automatically exported from code.google.com/p/touchcode
0 stars 0 forks source link

XPath & Default Namespaces #4

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
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];

Original issue reported on code.google.com by rick.hoi...@gmail.com on 4 Apr 2008 at 5:30

GoogleCodeExporter commented 8 years ago
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.

Original comment by jwight on 4 Apr 2008 at 6:06

GoogleCodeExporter commented 8 years ago
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?

Original comment by atomicb...@gmail.com on 6 Apr 2008 at 12:08

GoogleCodeExporter commented 8 years ago
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.

Original comment by jwight on 6 Apr 2008 at 12:12

GoogleCodeExporter commented 8 years ago
Fix made for Tom's issue in ticket #9

Original comment by jwight on 8 Apr 2008 at 3:36

GoogleCodeExporter commented 8 years ago
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.

Original comment by jtban...@gmail.com on 13 Jul 2008 at 5:00

GoogleCodeExporter commented 8 years ago
@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.

Original comment by jwight on 21 Jul 2008 at 4:37

GoogleCodeExporter commented 8 years ago
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

Original comment by surut...@gmail.com on 11 Jan 2009 at 12:38