mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
* Source/NSXMLNode.m (execute_xpath): Clean up.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@35012 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
a5c6cfa9f7
commit
18e25df75a
2 changed files with 107 additions and 103 deletions
|
@ -1,3 +1,7 @@
|
|||
2012-03-27 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/NSXMLNode.m (execute_xpath): Clean up.
|
||||
|
||||
2012-03-27 Niels Grewe <niels.grewe@halbordnung.de>
|
||||
* configure.ac
|
||||
* config.mak.in
|
||||
|
|
|
@ -729,77 +729,27 @@ clearPrivatePointers(xmlNodePtr aNode)
|
|||
// FIXME: Handle more node types
|
||||
}
|
||||
|
||||
static int
|
||||
register_namespaces(xmlXPathContextPtr xpathCtx, const xmlChar* nsList)
|
||||
{
|
||||
xmlChar* nsListDup;
|
||||
xmlChar* prefix;
|
||||
xmlChar* href;
|
||||
xmlChar* next;
|
||||
|
||||
assert(xpathCtx);
|
||||
assert(nsList);
|
||||
|
||||
nsListDup = xmlStrdup(nsList);
|
||||
if (nsListDup == NULL)
|
||||
{
|
||||
NSLog(@"Error: unable to strdup namespaces list");
|
||||
return -1;
|
||||
}
|
||||
|
||||
next = nsListDup;
|
||||
while (next != NULL)
|
||||
{
|
||||
/* skip spaces */
|
||||
while ((*next) == ' ') next++;
|
||||
if ((*next) == '\0') break;
|
||||
|
||||
/* find prefix */
|
||||
prefix = next;
|
||||
next = (xmlChar*)xmlStrchr(next, '=');
|
||||
if (next == NULL)
|
||||
{
|
||||
NSLog(@"Error: invalid namespaces list format");
|
||||
xmlFree(nsListDup);
|
||||
return -1;
|
||||
}
|
||||
*(next++) = '\0';
|
||||
|
||||
/* find href */
|
||||
href = next;
|
||||
next = (xmlChar*)xmlStrchr(next, ' ');
|
||||
if (next != NULL)
|
||||
{
|
||||
*(next++) = '\0';
|
||||
}
|
||||
|
||||
/* do register namespace */
|
||||
if (xmlXPathRegisterNs(xpathCtx, prefix, href) != 0)
|
||||
{
|
||||
NSLog(@"Error: unable to register NS with prefix=\"%s\""
|
||||
@" and href=\"%s\"", prefix, href);
|
||||
xmlFree(nsListDup);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
xmlFree(nsListDup);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static NSArray *
|
||||
execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
|
||||
execute_xpath(xmlNodePtr node, NSString *xpath_exp, NSDictionary *constants,
|
||||
BOOL nodesOnly, NSError **error)
|
||||
{
|
||||
xmlNodePtr node = [xmlNode _node];
|
||||
xmlDocPtr doc = node->doc;
|
||||
NSMutableArray *result = [NSMutableArray arrayWithCapacity: 10];
|
||||
xmlChar* xpathExpr = (xmlChar *)XMLSTRING(xpath_exp);
|
||||
xmlChar* nsList = (xmlChar *)XMLSTRING(nmspaces);
|
||||
NSMutableArray *result = nil;
|
||||
const xmlChar* xpathExpr = XMLSTRING(xpath_exp);
|
||||
xmlXPathContextPtr xpathCtx = NULL;
|
||||
xmlXPathObjectPtr xpathObj = NULL;
|
||||
xmlNodeSetPtr nodeset = NULL;
|
||||
xmlNodePtr cur = NULL;
|
||||
int i = 0;
|
||||
xmlNodePtr rootNode = NULL;
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
*error = NULL;
|
||||
}
|
||||
|
||||
if (doc == NULL)
|
||||
{
|
||||
// FIXME: Create temporary document
|
||||
return nil;
|
||||
}
|
||||
|
||||
assert(xpathExpr);
|
||||
|
||||
|
@ -811,18 +761,41 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
|
|||
return nil;
|
||||
}
|
||||
|
||||
/* Register namespaces from list (if any) */
|
||||
if ((nsList != NULL) && (register_namespaces(xpathCtx, nsList) < 0))
|
||||
// provide a context for relative paths
|
||||
xpathCtx->node = node;
|
||||
|
||||
/* Register namespaces from root node (if any) */
|
||||
rootNode = xmlDocGetRootElement(doc);
|
||||
if (rootNode != NULL)
|
||||
{
|
||||
NSLog(@"Error: failed to register namespaces list \"%s\"", nsList);
|
||||
xmlXPathFreeContext(xpathCtx);
|
||||
return nil;
|
||||
xmlNsPtr ns = rootNode->nsDef;
|
||||
|
||||
while (ns != NULL)
|
||||
{
|
||||
xmlXPathRegisterNs(xpathCtx, ns->prefix, ns->href);
|
||||
ns = ns->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (![xpath_exp hasPrefix: @"/"])
|
||||
// Add constants
|
||||
if (constants != nil)
|
||||
{
|
||||
// provide a context for relative paths
|
||||
xpathCtx->node = node;
|
||||
NSEnumerator *keyEnum = [constants keyEnumerator];
|
||||
NSString *key;
|
||||
|
||||
while ((key = [keyEnum nextObject]) != nil)
|
||||
{
|
||||
id obj = [constants objectForKey: key];
|
||||
const xmlChar *name = XMLSTRING(key);
|
||||
|
||||
// FIXME: Add more conversions
|
||||
if ([obj isKindOfClass: [NSString class]])
|
||||
{
|
||||
xmlXPathObjectPtr value = xmlXPathNewString(XMLSTRING(obj));
|
||||
|
||||
xmlXPathRegisterVariable(xpathCtx, name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Evaluate xpath expression */
|
||||
|
@ -835,30 +808,43 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
|
|||
}
|
||||
|
||||
/* results */
|
||||
nodeset = xpathObj->nodesetval;
|
||||
/*
|
||||
if (nodeset == NULL || nodeset->nodeNr == 0)
|
||||
if (xpathObj->type == XPATH_NODESET)
|
||||
{
|
||||
xpathObj = xmlXPathEval(xpathExpr, xpathCtx);
|
||||
if (xpathObj != NULL)
|
||||
nodeset = xpathObj->nodesetval;
|
||||
if (nodeset)
|
||||
NSLog(@"Succeeded in evaluating as a path, using xmlXPathEval");
|
||||
xmlNodeSetPtr nodeset = NULL;
|
||||
|
||||
nodeset = xpathObj->nodesetval;
|
||||
if (!xmlXPathNodeSetIsEmpty(nodeset))
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/* Collect results */
|
||||
result = [NSMutableArray arrayWithCapacity: nodeset->nodeNr];
|
||||
for (i = 0; i < nodeset->nodeNr; i++)
|
||||
{
|
||||
id obj = nil;
|
||||
xmlNodePtr cur = NULL;
|
||||
|
||||
cur = nodeset->nodeTab[i];
|
||||
obj = [NSXMLNode _objectForNode: cur];
|
||||
if (obj)
|
||||
{
|
||||
[result addObject: obj];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (nodeset)
|
||||
else if (!nodesOnly)
|
||||
{
|
||||
/* Collect results */
|
||||
for (i = 0; i < nodeset->nodeNr; i++)
|
||||
{
|
||||
id obj = nil;
|
||||
cur = nodeset->nodeTab[i];
|
||||
obj = [NSXMLNode _objectForNode: cur];
|
||||
if (obj)
|
||||
{
|
||||
[result addObject: obj];
|
||||
}
|
||||
}
|
||||
switch (xpathObj->type)
|
||||
{
|
||||
case XPATH_STRING:
|
||||
result = [NSMutableArray arrayWithObject:
|
||||
StringFromXMLStringPtr(xpathObj->stringval)];
|
||||
break;
|
||||
// FIXME: Handle other types
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
|
@ -872,12 +858,19 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
|
|||
|
||||
+ (void) initialize
|
||||
{
|
||||
xmlCheckVersion(LIBXML_VERSION);
|
||||
// Protect against libxml2 not being correctly set up on Windows.
|
||||
// See: http://www.linuxquestions.org/questions/programming-9/%5Bsolved%5Dusing-libxml2-on-mingw-xmlfree-crashes-839802/
|
||||
if (!xmlFree)
|
||||
if (self == [NSXMLNode class])
|
||||
{
|
||||
xmlMemGet(&xmlFree, &xmlMalloc, &xmlRealloc, NULL);
|
||||
xmlCheckVersion(LIBXML_VERSION);
|
||||
|
||||
// Protect against libxml2 not being correctly set up on Windows.
|
||||
// See: http://www.linuxquestions.org/questions/programming-9/%5Bsolved%5Dusing-libxml2-on-mingw-xmlfree-crashes-839802/
|
||||
if (!xmlFree)
|
||||
{
|
||||
xmlMemGet(&xmlFree, &xmlMalloc, &xmlRealloc, NULL);
|
||||
}
|
||||
|
||||
// Switch off default
|
||||
xmlKeepBlanksDefault(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2060,11 +2053,18 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
|
|||
|
||||
- (NSArray*) nodesForXPath: (NSString*)anxpath error: (NSError**)error
|
||||
{
|
||||
if (error != NULL)
|
||||
xmlNodePtr node = internal->node;
|
||||
|
||||
if (NSXMLInvalidKind == internal->kind)
|
||||
{
|
||||
*error = NULL;
|
||||
return nil;
|
||||
}
|
||||
return execute_xpath(self, anxpath, NULL);
|
||||
if (node->type == XML_NAMESPACE_DECL)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
return execute_xpath(node, anxpath, nil, YES, error);
|
||||
}
|
||||
|
||||
- (NSArray*) objectsForXQuery: (NSString*)xquery
|
||||
|
|
Loading…
Reference in a new issue