* Source/NSXMLElement.m,

* Source/NSXMLNode.m: Better support for namespaces. Corrected
-_nodeFollowingInNaturalDirection:, -setStringValue: and
-XMLStringWithOptions:


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@34999 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Fred Kiefer 2012-03-26 23:11:52 +00:00
parent 132de12a73
commit 517ef2d55f
3 changed files with 136 additions and 55 deletions

View file

@ -1,3 +1,9 @@
2012-03-27 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSXMLElement.m,
* Source/NSXMLNode.m: Better support for namespaces. Corrected
-_nodeFollowingInNaturalDirection:, -setStringValue: and -XMLStringWithOptions:
2012-03-26 Niels Grewe <niels.grewe@halbordnung.de>
* Headers/Foundation/NSOperation.h

View file

@ -171,8 +171,10 @@ extern void ensure_oldNs(xmlNodePtr node);
{
if (cur->type == XML_ELEMENT_NODE)
{
// FIXME: no namespace or default namespace
if ((xmlStrcmp(xmlName, cur->name) == 0) && (cur->ns == NULL))
// no namespace or default namespace
if ((xmlStrcmp(xmlName, cur->name) == 0) &&
((cur->ns == NULL) || (cur->ns->prefix == NULL) ||
(xmlStrcmp(cur->ns->prefix, (const xmlChar*)"") == 0)))
{
NSXMLNode *node = [NSXMLNode _objectForNode: cur];
[results addObject: node];
@ -196,17 +198,21 @@ extern void ensure_oldNs(xmlNodePtr node);
{
if (cur->type == XML_ELEMENT_NODE)
{
xmlNsPtr childNS = parentNS;
if (cur->nsDef != NULL)
if (xmlStrcmp(xmlName, cur->name) == 0)
{
childNS = xmlSearchNsByHref(internal->node->doc, cur, href);
}
xmlNsPtr childNS = parentNS;
if ((cur->ns == childNS) ||
((cur->ns == NULL) && (xmlStrcmp(childNS->prefix, (const xmlChar*)"") == 0)))
{
if (xmlStrcmp(xmlName, cur->name) == 0)
if (cur->nsDef != NULL)
{
childNS = xmlSearchNsByHref(internal->node->doc, cur, href);
}
if (((childNS != NULL) &&
((cur->ns == childNS) ||
((cur->ns == NULL) &&
(xmlStrcmp(childNS->prefix, (const xmlChar*)"") == 0)))) ||
((cur->ns != NULL) && (xmlStrcmp(cur->ns->href, href) == 0)))
{
NSXMLNode *node = [NSXMLNode _objectForNode: cur];
[results addObject: node];
@ -449,6 +455,7 @@ extern void ensure_oldNs(xmlNodePtr node);
{
xmlNsPtr ns = xmlCopyNamespace((xmlNsPtr)[aNamespace _node]);
xmlNodePtr node = internal->node;
const xmlChar *prefix = ns->prefix;
if (node->nsDef == NULL)
{
@ -458,7 +465,6 @@ extern void ensure_oldNs(xmlNodePtr node);
{
xmlNsPtr cur = node->nsDef;
xmlNsPtr last = NULL;
const xmlChar *prefix = ns->prefix;
while (cur != NULL)
{
@ -498,6 +504,12 @@ extern void ensure_oldNs(xmlNodePtr node);
}
}
// Are we setting a default namespace?
if ((node->ns == NULL) && (xmlStrcmp(prefix, (const xmlChar*)"") == 0))
{
node->ns = ns;
}
// Need to replace fake namespaces in subnodes
cleanup_namespaces(node, ns);
}
@ -544,9 +556,11 @@ extern void ensure_oldNs(xmlNodePtr node);
NSEnumerator *en = [namespaces objectEnumerator];
NSXMLNode *namespace = nil;
// FIXME: Remove old namespaces
// xmlFreeNsList(internal->node->nsDef);
// internal->node->nsDef = NULL;
// Remove old namespaces
xmlFreeNsList(internal->node->nsDef);
internal->node->nsDef = NULL;
// Add new ones
while ((namespace = (NSXMLNode *)[en nextObject]) != nil)
{
[self addNamespace: namespace];
@ -576,13 +590,23 @@ extern void ensure_oldNs(xmlNodePtr node);
- (NSXMLNode*) namespaceForPrefix: (NSString*)name
{
const xmlChar *prefix = XMLSTRING(name);
xmlNodePtr node = internal->node;
xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
if (ns)
if (name != nil)
{
return [NSXMLNode _objectForNode: (xmlNodePtr)xmlCopyNamespace(ns)];
const xmlChar *prefix = XMLSTRING(name);
xmlNodePtr node = internal->node;
xmlNsPtr ns;
ns = xmlSearchNs(node->doc, node, prefix);
if ((ns == NULL) && ([name length] == 0))
{
prefix = NULL;
ns = xmlSearchNs(node->doc, node, prefix);
}
if (ns != NULL)
{
return [NSXMLNode _objectForNode: (xmlNodePtr)xmlCopyNamespace(ns)];
}
}
return nil;

View file

@ -29,6 +29,7 @@
#define GSInternal NSXMLNodeInternal
#define GS_XMLNODETYPE xmlNode
#import "Foundation/NSCharacterSet.h"
#import "NSXMLPrivate.h"
#import "GSInternal.h"
GS_PRIVATE_INTERNAL(NSXMLNode)
@ -53,8 +54,10 @@ cleanup_namespaces(xmlNodePtr node, xmlNsPtr ns)
if (ns1 != NULL &&
(((ns1->href == NULL) &&
(xmlStrcmp(ns1->prefix, ns->prefix) == 0)) ||
/*
((ns1->prefix == NULL) &&
(xmlStrcmp(ns1->href, ns->href) == 0)) ||
*/
((xmlStrcmp(ns1->prefix, ns->prefix) == 0) &&
(xmlStrcmp(ns1->href, ns->href) == 0))))
{
@ -483,8 +486,11 @@ isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
xmlNodePtr node = internal->node;
xmlNodePtr children;
if (node->type == XML_NAMESPACE_DECL)
return NULL;
if ((node->type == XML_NAMESPACE_DECL) ||
(node->type == XML_ATTRIBUTE_NODE))
{
return NULL;
}
children = node->children;
if (!children)
@ -544,6 +550,7 @@ isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
resolved = YES;
}
}
/*
else if (ns->prefix == NULL)
{
xmlNsPtr ns1 = xmlSearchNsByHref(parentNode->doc, parentNode, ns->href);
@ -554,6 +561,7 @@ isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
resolved = YES;
}
}
*/
if (!resolved)
{
xmlNsPtr cur = ns;
@ -1043,7 +1051,9 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
NSString *result = @"";
if (NULL == xmlName)
return nil;
{
return result;
}
localName = xmlSplitQName2(xmlName, &prefix);
if (NULL != prefix)
@ -1541,15 +1551,13 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
NSXMLNode *candidate = nil;
NSXMLNodeKind kind;
/* Node walking is a depth-first thingy. Hence, we consider children first: */
if (0 != [self childCount])
if (forward)
{
NSUInteger theIndex = 0;
if (NO == forward)
{
theIndex = [self childCount] - 1;
}
candidate = [[self children] objectAtIndex: theIndex];
/* Node walking is a depth-first thingy. Hence, we consider children first: */
if (0 != [self childCount])
{
candidate = [[self children] objectAtIndex: 0];
}
}
/* If there are no children, we move on to siblings: */
@ -1575,6 +1583,16 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
return nil;
}
if (!forward)
{
/* Node walking is a depth-first thingy. Hence, we consider children first: */
while (0 != [candidate childCount])
{
NSUInteger theIndex = [candidate childCount] - 1;
candidate = [[candidate children] objectAtIndex: theIndex];
}
}
/* Sanity check: Namespace and attribute nodes are skipped: */
kind = [candidate kind];
if ((NSXMLAttributeKind == kind) || (NSXMLNamespaceKind == kind))
@ -1637,7 +1655,7 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
}
if (XML_NAMESPACE_DECL == node->type)
{
return nil;
return @"";
}
if (XML_ELEMENT_NODE != node->type)
{
@ -1836,6 +1854,22 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
}
else
{
// Remove all child nodes except attributes
if (internal->subNodes)
{
NSArray *subNodes = [internal->subNodes copy];
NSEnumerator *enumerator = [subNodes objectEnumerator];
NSXMLNode *subNode;
while ((subNode = [enumerator nextObject]) != nil)
{
if ([subNode kind] != NSXMLAttributeKind)
{
[subNode detach];
}
}
}
if (resolve == NO)
{
xmlNodeSetContent(node, XMLSTRING(string));
@ -1880,31 +1914,39 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
node->ns->href = xmlStrdup(uri);
return;
}
{
xmlNsPtr oldNs;
ensure_oldNs(node);
// Fake the name space and fix it later
// This function is private, so re reimplemt it.
//ns = xmlDOMWrapStoreNs(node->doc, NULL, prefix);
oldNs = node->doc->oldNs;
while (oldNs)
{
if (oldNs->href != NULL && xmlStrEqual(oldNs->href, uri))
{
ns = oldNs;
break;
}
if (oldNs->next == NULL)
/*
if (node->type == XML_ELEMENT_NODE)
{
//ns = xmlNewNs(node, uri, (const xmlChar *)"");
ns = xmlNewNs(node, uri, NULL);
}
else
*/
{
xmlNsPtr oldNs;
ensure_oldNs(node);
// Fake the name space and fix it later
// This function is private, so re reimplemt it.
//ns = xmlDOMWrapStoreNs(node->doc, NULL, prefix);
oldNs = node->doc->oldNs;
while (oldNs)
{
if (oldNs->href != NULL && xmlStrEqual(oldNs->href, uri))
{
ns = oldNs;
break;
}
if (oldNs->next == NULL)
{
ns = xmlNewNs(NULL, uri, NULL);
oldNs->next = ns;
break;
}
oldNs = oldNs->next;
}
}
oldNs = oldNs->next;
}
}
}
xmlSetNs(node, ns);
@ -1961,7 +2003,8 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
}
#endif
#if LIBXML_VERSION >= 20622
if (options & NSXMLNodeCompactEmptyElement)
//NSXMLNodeExpandEmptyElement is the default
if ((options & NSXMLNodeCompactEmptyElement) == 0)
{
xmlOptions |= XML_SAVE_NO_EMPTY;
}
@ -1998,7 +2041,15 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
string = StringFromXMLString(buf, len);
xmlBufferFree(buffer);
return string;
if ([self kind] == NSXMLTextKind)
{
return string;
}
else
{
return [string stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
}
- (NSString*) XPath