mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
* 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:
parent
132de12a73
commit
517ef2d55f
3 changed files with 136 additions and 55 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue