Hi guys.
I'm currently working on an iPhone application and I'm am using the libxml2 framework together with TouchXML to parse XML data. This has been working for me, until yesterday. (Scroll down for a short summary of the problem, it's not that hard to explain but I want to be clear the first time
)
Let's say I have the following XML structure:
I select all of the solution elements and create an object for it. I then tell that object to parse it's children, by passing the solution element to the object. That will perform some XPath queries on the solution element as well. The problem is, the xmlXPathContextPtr which is created to perform the XPath query is created using the document, not just the element. I thought I had solved that problem, but that's not the case. If I print out the contents of the node where the XPath query is performed on, I only get the element I want. But when I print all the results nodes, I get all the nodes which are children (that's okay) and all the nodes which are NOT children of the node, the ones I don't want. Here's some code:
SUMMARY:
It seems to be a serious problem, but I think it can be solved quite easily but that I'm just overlooking the solution. I basically only want to select the children of ONE node, not of the whole document. Passing only the node to the context works in some cases, but not in all as I discovered. My question is how to solve this, do I have to create a new xmlDocPtr out of the xmlNodePtr so the specific node will be the whole document? To me, that does not sound like the right solution.
Thanks in advance, if you need any more information, please ask!
EDIT. After a little more trying to solve the problem, I came up with the idea of temporarily unsetting the last-child's parent, so that the XPath parsing mechanism thinks it is at the end of the document. That does actually work, although I don't think it's the proper way to do so.
I'm currently working on an iPhone application and I'm am using the libxml2 framework together with TouchXML to parse XML data. This has been working for me, until yesterday. (Scroll down for a short summary of the problem, it's not that hard to explain but I want to be clear the first time
Let's say I have the following XML structure:
Code:
<?xml version="1.0"?>
<solutions>
<solution>
<options>
<option>12</option>
<option>53</option>
<option>65</option>
</options>
</solution>
<solution>
<options>
<option>14</option>
<option>55</option>
<option>67</option>
</options>
</solution>
</solutions>
I select all of the solution elements and create an object for it. I then tell that object to parse it's children, by passing the solution element to the object. That will perform some XPath queries on the solution element as well. The problem is, the xmlXPathContextPtr which is created to perform the XPath query is created using the document, not just the element. I thought I had solved that problem, but that's not the case. If I print out the contents of the node where the XPath query is performed on, I only get the element I want. But when I print all the results nodes, I get all the nodes which are children (that's okay) and all the nodes which are NOT children of the node, the ones I don't want. Here's some code:
Code:
/* ROOT PARSER */
- (void)parseXMLData:(NSData *)data {
// Get all the elements
NSError *error = nil;
CXMLDocument *document = [[CXMLDocument alloc] initWithData:data options:0 error:&error];
// Check for errors
if(error != nil){
[document release];
// TODO: Handle error
return;
}
// Select solution
NSArray *solutions = [[document rootElement] nodesForXPath:@"//solution" error:NULL];
// Create solutions array
if(_solutions == nil){
_solutions = [[NSMutableArray alloc] init];
}
for(CXMLElement *solutionElement in solutions){
Solution *solution = [[Solution alloc] init];
[solution parseXMLElement:solutionElement];
[_solutions addObject:solution];
[solution release];
}
[document release];
}
/* SOLUTION PARSER */
- (void)parseXMLElement:(CXMLElement *)element {
// Select options
NSArray *options = [element nodesForXPath:@"//options/option" error:NULL];
for(CXMLElement *element in options){
NSLog(@"%@", element);
}
}
/* TouchXML ADJUSTMENTS */
/* -[CXMLNode nodesForXPath:error:] */
// Creation of context
xmlXPathContextPtr theXPathContext = xmlXPathNewContext((xmlDocPtr)_node);
theXPathContext->node = _node;
SUMMARY:
It seems to be a serious problem, but I think it can be solved quite easily but that I'm just overlooking the solution. I basically only want to select the children of ONE node, not of the whole document. Passing only the node to the context works in some cases, but not in all as I discovered. My question is how to solve this, do I have to create a new xmlDocPtr out of the xmlNodePtr so the specific node will be the whole document? To me, that does not sound like the right solution.
Thanks in advance, if you need any more information, please ask!
EDIT. After a little more trying to solve the problem, I came up with the idea of temporarily unsetting the last-child's parent, so that the XPath parsing mechanism thinks it is at the end of the document. That does actually work, although I don't think it's the proper way to do so.