mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-08 07:20:48 +00:00
* Source/NSXMLNode.m: Further clean up.
* Source/NSXMLDTDNode.m (-initWithXMLString:): Move comment about missing code to here. * Source/NSXMLElement.m (-initWithName:stringValue:): Move subnode creation to here. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@34806 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
b4b1fd5646
commit
a2f291260f
4 changed files with 496 additions and 488 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2012-02-22 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
|
* Source/NSXMLNode.m: Further clean up.
|
||||||
|
* Source/NSXMLDTDNode.m (-initWithXMLString:): Move comment about
|
||||||
|
missing code to here.
|
||||||
|
* Source/NSXMLElement.m (-initWithName:stringValue:): Move subnode
|
||||||
|
creation to here.
|
||||||
|
|
||||||
2012-02-21 Fred Kiefer <FredKiefer@gmx.de>
|
2012-02-21 Fred Kiefer <FredKiefer@gmx.de>
|
||||||
|
|
||||||
* Source/NSXMLNode.m: Clean up helper functions.
|
* Source/NSXMLNode.m: Clean up helper functions.
|
||||||
|
|
|
@ -60,6 +60,9 @@ GS_PRIVATE_INTERNAL(NSXMLDTDNode)
|
||||||
|
|
||||||
- (id) initWithXMLString: (NSString*)string
|
- (id) initWithXMLString: (NSString*)string
|
||||||
{
|
{
|
||||||
|
// internal->node = xmlNewDtd(NULL,NULL,NULL);
|
||||||
|
// TODO: Parse the string and get the info to create this...
|
||||||
|
|
||||||
[self notImplemented: _cmd];
|
[self notImplemented: _cmd];
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,11 @@ extern void clearPrivatePointers(xmlNodePtr aNode);
|
||||||
{
|
{
|
||||||
if ([self initWithName: name URI: nil] != nil)
|
if ([self initWithName: name URI: nil] != nil)
|
||||||
{
|
{
|
||||||
[self setObjectValue: string];
|
NSXMLNode *t;
|
||||||
|
t = [[NSXMLNode alloc] initWithKind: NSXMLTextKind];
|
||||||
|
[t setStringValue: string];
|
||||||
|
[self addChild: t];
|
||||||
|
[t release];
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,6 +196,8 @@ BOOL isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
|
||||||
- (void) _addSubNode:(NSXMLNode *)subNode;
|
- (void) _addSubNode:(NSXMLNode *)subNode;
|
||||||
- (void) _removeSubNode:(NSXMLNode *)subNode;
|
- (void) _removeSubNode:(NSXMLNode *)subNode;
|
||||||
- (id) _initWithNode:(xmlNodePtr)node kind:(NSXMLNodeKind)kind;
|
- (id) _initWithNode:(xmlNodePtr)node kind:(NSXMLNodeKind)kind;
|
||||||
|
- (xmlNodePtr) _childNodeAtIndex: (NSUInteger)index;
|
||||||
|
- (void) _insertChild: (NSXMLNode*)child atIndex: (NSUInteger)index;
|
||||||
- (void) _updateExternalRetains;
|
- (void) _updateExternalRetains;
|
||||||
- (void) _invalidate;
|
- (void) _invalidate;
|
||||||
@end
|
@end
|
||||||
|
@ -219,41 +221,39 @@ BOOL isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
|
||||||
|
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
xmlElementType type = node->type;
|
|
||||||
// NSXMLNodeKind kind = 0;
|
|
||||||
result = node->_private;
|
result = node->_private;
|
||||||
|
|
||||||
if (result == nil)
|
if (result == nil)
|
||||||
{
|
{
|
||||||
|
xmlElementType type = node->type;
|
||||||
|
|
||||||
switch(type)
|
switch(type)
|
||||||
{
|
{
|
||||||
case(XML_DOCUMENT_NODE):
|
case XML_DOCUMENT_NODE:
|
||||||
result = [[NSXMLDocument alloc] _initWithNode: node kind: NSXMLDocumentKind];
|
result = [[NSXMLDocument alloc] _initWithNode: node kind: NSXMLDocumentKind];
|
||||||
break;
|
break;
|
||||||
case(XML_ELEMENT_NODE):
|
case XML_ELEMENT_NODE:
|
||||||
result = [[NSXMLElement alloc] _initWithNode: node kind: NSXMLElementKind];
|
result = [[NSXMLElement alloc] _initWithNode: node kind: NSXMLElementKind];
|
||||||
break;
|
break;
|
||||||
case(XML_TEXT_NODE):
|
case XML_TEXT_NODE:
|
||||||
result = [[self alloc] _initWithNode: node kind: NSXMLTextKind];
|
result = [[self alloc] _initWithNode: node kind: NSXMLTextKind];
|
||||||
break;
|
break;
|
||||||
case(XML_PI_NODE):
|
case XML_PI_NODE:
|
||||||
result = [[self alloc] _initWithNode: node kind: NSXMLProcessingInstructionKind];
|
result = [[self alloc] _initWithNode: node kind: NSXMLProcessingInstructionKind];
|
||||||
break;
|
break;
|
||||||
case(XML_COMMENT_NODE):
|
case XML_COMMENT_NODE:
|
||||||
result = [[self alloc] _initWithNode: node kind: NSXMLCommentKind];
|
result = [[self alloc] _initWithNode: node kind: NSXMLCommentKind];
|
||||||
break;
|
break;
|
||||||
case(XML_ATTRIBUTE_NODE):
|
case XML_ATTRIBUTE_NODE:
|
||||||
result = [[self alloc] _initWithNode: node kind: NSXMLAttributeKind];
|
result = [[self alloc] _initWithNode: node kind: NSXMLAttributeKind];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
NSLog(@"ERROR: _objectForNode: called with a node of type %d", type);
|
NSLog(@"ERROR: _objectForNode: called with a node of type %d", type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//[result _setNode:node];
|
|
||||||
AUTORELEASE(result);
|
AUTORELEASE(result);
|
||||||
if (node->parent)
|
if (node->parent)
|
||||||
{
|
{
|
||||||
NSXMLNode *parent = [NSXMLNode _objectForNode:node->parent];
|
NSXMLNode *parent = [self _objectForNode: node->parent];
|
||||||
[parent _addSubNode: result];
|
[parent _addSubNode: result];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -404,6 +404,98 @@ BOOL isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (xmlNodePtr) _childNodeAtIndex: (NSUInteger)index
|
||||||
|
{
|
||||||
|
NSUInteger count = 0;
|
||||||
|
xmlNodePtr node = (xmlNodePtr)(internal->node);
|
||||||
|
xmlNodePtr children = node->children;
|
||||||
|
if (!children)
|
||||||
|
return NULL; // the Cocoa docs say it returns nil if there are no children
|
||||||
|
|
||||||
|
for (children = node->children; children != NULL && count != index; children = children->next)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count != index)
|
||||||
|
[NSException raise: NSRangeException format: @"child index too large"];
|
||||||
|
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) _insertChild: (NSXMLNode*)child atIndex: (NSUInteger)index
|
||||||
|
{
|
||||||
|
// this private method provides the common insertion implementation used by NSXMLElement and NSXMLDocument
|
||||||
|
|
||||||
|
// Get all of the nodes...
|
||||||
|
xmlNodePtr parentNode = MY_NODE; // we are the parent
|
||||||
|
xmlNodePtr childNode = ((xmlNodePtr)[child _node]);
|
||||||
|
xmlNodePtr curNode = [self _childNodeAtIndex: index];
|
||||||
|
BOOL mergeTextNodes = NO; // is there a defined option for this?
|
||||||
|
|
||||||
|
if (mergeTextNodes || childNode->type == XML_ATTRIBUTE_NODE)
|
||||||
|
{
|
||||||
|
// this uses the built-in libxml functions which merge adjacent text nodes
|
||||||
|
xmlNodePtr addedNode = NULL;
|
||||||
|
//curNode = ((xmlNodePtr)[cur _node]);
|
||||||
|
|
||||||
|
if (curNode == NULL) //(0 == childCount || index == childCount)
|
||||||
|
{
|
||||||
|
addedNode = xmlAddChild(parentNode, childNode);
|
||||||
|
}
|
||||||
|
else //if(index < childCount)
|
||||||
|
{
|
||||||
|
addedNode = xmlAddPrevSibling(curNode, childNode);
|
||||||
|
}
|
||||||
|
if (addedNode != childNode)
|
||||||
|
{
|
||||||
|
[child _setNode:NULL];
|
||||||
|
child = [NSXMLNode _objectForNode:addedNode];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// here we avoid merging adjacent text nodes by linking the new node in "by hand"
|
||||||
|
childNode->parent = parentNode;
|
||||||
|
if (curNode)
|
||||||
|
{
|
||||||
|
// insert childNode before an existing node curNode
|
||||||
|
xmlNodePtr prevNode = curNode->prev;
|
||||||
|
curNode->prev = childNode;
|
||||||
|
childNode->next = curNode;
|
||||||
|
if (prevNode)
|
||||||
|
{
|
||||||
|
childNode->prev = prevNode;
|
||||||
|
prevNode->next = childNode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// in this case, this is the new "first child", so update our parent to point to it
|
||||||
|
parentNode->children = childNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// not inserting before an existing node... add as new "last child"
|
||||||
|
xmlNodePtr formerLastChild = parentNode->last;
|
||||||
|
if (formerLastChild)
|
||||||
|
{
|
||||||
|
formerLastChild->next = childNode;
|
||||||
|
childNode->prev = formerLastChild;
|
||||||
|
parentNode->last = childNode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no former children -- this is the first
|
||||||
|
parentNode->children = childNode;
|
||||||
|
parentNode->last = childNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[self _addSubNode:child];
|
||||||
|
}
|
||||||
|
|
||||||
- (void) _invalidate
|
- (void) _invalidate
|
||||||
{
|
{
|
||||||
internal->kind = NSXMLInvalidKind;
|
internal->kind = NSXMLInvalidKind;
|
||||||
|
@ -435,13 +527,15 @@ int register_namespaces(xmlXPathContextPtr xpathCtx,
|
||||||
assert(nsList);
|
assert(nsList);
|
||||||
|
|
||||||
nsListDup = xmlStrdup(nsList);
|
nsListDup = xmlStrdup(nsList);
|
||||||
if(nsListDup == NULL) {
|
if (nsListDup == NULL)
|
||||||
|
{
|
||||||
NSLog(@"Error: unable to strdup namespaces list");
|
NSLog(@"Error: unable to strdup namespaces list");
|
||||||
return(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
next = nsListDup;
|
next = nsListDup;
|
||||||
while(next != NULL) {
|
while (next != NULL)
|
||||||
|
{
|
||||||
/* skip spaces */
|
/* skip spaces */
|
||||||
while((*next) == ' ') next++;
|
while((*next) == ' ') next++;
|
||||||
if((*next) == '\0') break;
|
if((*next) == '\0') break;
|
||||||
|
@ -449,30 +543,34 @@ int register_namespaces(xmlXPathContextPtr xpathCtx,
|
||||||
/* find prefix */
|
/* find prefix */
|
||||||
prefix = next;
|
prefix = next;
|
||||||
next = (xmlChar*)xmlStrchr(next, '=');
|
next = (xmlChar*)xmlStrchr(next, '=');
|
||||||
if(next == NULL) {
|
if (next == NULL)
|
||||||
|
{
|
||||||
NSLog(@"Error: invalid namespaces list format");
|
NSLog(@"Error: invalid namespaces list format");
|
||||||
xmlFree(nsListDup);
|
xmlFree(nsListDup);
|
||||||
return(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
*(next++) = '\0';
|
*(next++) = '\0';
|
||||||
|
|
||||||
/* find href */
|
/* find href */
|
||||||
href = next;
|
href = next;
|
||||||
next = (xmlChar*)xmlStrchr(next, ' ');
|
next = (xmlChar*)xmlStrchr(next, ' ');
|
||||||
if(next != NULL) {
|
if (next != NULL)
|
||||||
|
{
|
||||||
*(next++) = '\0';
|
*(next++) = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do register namespace */
|
/* do register namespace */
|
||||||
if(xmlXPathRegisterNs(xpathCtx, prefix, href) != 0) {
|
if (xmlXPathRegisterNs(xpathCtx, prefix, href) != 0)
|
||||||
NSLog(@"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"", prefix, href);
|
{
|
||||||
|
NSLog(@"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"",
|
||||||
|
prefix, href);
|
||||||
xmlFree(nsListDup);
|
xmlFree(nsListDup);
|
||||||
return(-1);
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xmlFree(nsListDup);
|
xmlFree(nsListDup);
|
||||||
return(0);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSArray *execute_xpath(NSXMLNode *node,
|
NSArray *execute_xpath(NSXMLNode *node,
|
||||||
|
@ -560,14 +658,10 @@ NSArray *execute_xpath(NSXMLNode *node,
|
||||||
stringValue: (NSString*)stringValue
|
stringValue: (NSString*)stringValue
|
||||||
{
|
{
|
||||||
NSXMLNode *n;
|
NSXMLNode *n;
|
||||||
xmlAttrPtr node = xmlNewProp(NULL,
|
|
||||||
XMLSTRING(name),
|
|
||||||
XMLSTRING(stringValue));
|
|
||||||
|
|
||||||
n = [[[self alloc] initWithKind: NSXMLAttributeKind] autorelease];
|
n = [[[self alloc] initWithKind: NSXMLAttributeKind] autorelease];
|
||||||
[n setStringValue: stringValue];
|
[n setStringValue: stringValue];
|
||||||
[n setName: name];
|
[n setName: name];
|
||||||
[n _setNode: (void *)node];
|
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -577,15 +671,11 @@ NSArray *execute_xpath(NSXMLNode *node,
|
||||||
stringValue: (NSString*)stringValue
|
stringValue: (NSString*)stringValue
|
||||||
{
|
{
|
||||||
NSXMLNode *n;
|
NSXMLNode *n;
|
||||||
xmlAttrPtr node = xmlNewProp(NULL,
|
|
||||||
XMLSTRING(name),
|
|
||||||
XMLSTRING(stringValue));
|
|
||||||
|
|
||||||
n = [[[self alloc] initWithKind: NSXMLAttributeKind] autorelease];
|
n = [[[self alloc] initWithKind: NSXMLAttributeKind] autorelease];
|
||||||
[n setURI: URI];
|
[n setURI: URI];
|
||||||
[n setStringValue: stringValue];
|
[n setStringValue: stringValue];
|
||||||
[n setName: name];
|
[n setName: name];
|
||||||
[n _setNode: node];
|
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -593,11 +683,9 @@ NSArray *execute_xpath(NSXMLNode *node,
|
||||||
+ (id) commentWithStringValue: (NSString*)stringValue
|
+ (id) commentWithStringValue: (NSString*)stringValue
|
||||||
{
|
{
|
||||||
NSXMLNode *n;
|
NSXMLNode *n;
|
||||||
xmlNodePtr node = xmlNewComment(XMLSTRING(stringValue));
|
|
||||||
|
|
||||||
n = [[[self alloc] initWithKind: NSXMLCommentKind] autorelease];
|
n = [[[self alloc] initWithKind: NSXMLCommentKind] autorelease];
|
||||||
[n setStringValue: stringValue];
|
[n setStringValue: stringValue];
|
||||||
[n _setNode: node];
|
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -606,10 +694,7 @@ NSArray *execute_xpath(NSXMLNode *node,
|
||||||
{
|
{
|
||||||
NSXMLNode *n;
|
NSXMLNode *n;
|
||||||
|
|
||||||
n = [[[self alloc] initWithKind: NSXMLDTDKind] autorelease];
|
n = [[[NSXMLDTDNode alloc] initWithXMLString: string] autorelease];
|
||||||
[n setStringValue: string];
|
|
||||||
|
|
||||||
// internal->node = xmlNewDtd(NULL,NULL,NULL); // TODO: Parse the string and get the info to create this...
|
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -626,8 +711,7 @@ NSArray *execute_xpath(NSXMLNode *node,
|
||||||
{
|
{
|
||||||
NSXMLDocument *d;
|
NSXMLDocument *d;
|
||||||
|
|
||||||
d = [NSXMLDocument alloc];
|
d = [[[NSXMLDocument alloc] initWithRootElement: element] autorelease];
|
||||||
d = [[d initWithRootElement: element] autorelease];
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,19 +747,22 @@ NSArray *execute_xpath(NSXMLNode *node,
|
||||||
stringValue: (NSString*)string
|
stringValue: (NSString*)string
|
||||||
{
|
{
|
||||||
NSXMLElement *e;
|
NSXMLElement *e;
|
||||||
NSXMLNode *t;
|
|
||||||
|
|
||||||
e = [self elementWithName: name];
|
e = [self elementWithName: name stringValue: string];
|
||||||
t = [[self alloc] initWithKind: NSXMLTextKind];
|
|
||||||
[t setStringValue: string];
|
|
||||||
[e addChild: t];
|
|
||||||
[t release];
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSString*) localNameForName: (NSString*)name
|
+ (NSString*) localNameForName: (NSString*)name
|
||||||
{
|
{
|
||||||
return [self notImplemented: _cmd];
|
const xmlChar *xmlName = XMLSTRING(name);
|
||||||
|
xmlChar *prefix = NULL;
|
||||||
|
xmlChar *localName;
|
||||||
|
|
||||||
|
if (NULL == xmlName)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
localName = xmlSplitQName2(xmlName, &prefix);
|
||||||
|
return StringFromXMLStringPtr(localName);
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id) namespaceWithName: (NSString*)name
|
+ (id) namespaceWithName: (NSString*)name
|
||||||
|
@ -684,18 +771,61 @@ NSArray *execute_xpath(NSXMLNode *node,
|
||||||
NSXMLNode *n;
|
NSXMLNode *n;
|
||||||
|
|
||||||
n = [[[self alloc] initWithKind: NSXMLNamespaceKind] autorelease];
|
n = [[[self alloc] initWithKind: NSXMLNamespaceKind] autorelease];
|
||||||
|
[n setName: name];
|
||||||
[n setStringValue: stringValue];
|
[n setStringValue: stringValue];
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSXMLNode*) predefinedNamespaceForPrefix: (NSString*)name
|
+ (NSXMLNode*) predefinedNamespaceForPrefix: (NSString*)name
|
||||||
{
|
{
|
||||||
return [self notImplemented: _cmd];
|
// FIXME: We should cache these instances
|
||||||
|
if ([name isEqualToString: @"xml"])
|
||||||
|
{
|
||||||
|
return [self namespaceWithName: @"xml"
|
||||||
|
stringValue: @"http://www.w3.org/XML/1998/namespace"];
|
||||||
|
}
|
||||||
|
if ([name isEqualToString: @"xs"])
|
||||||
|
{
|
||||||
|
return [self namespaceWithName: @"xs"
|
||||||
|
stringValue: @"http://www.w3.org/2001/XMLSchema"];
|
||||||
|
}
|
||||||
|
if ([name isEqualToString: @"xsi"])
|
||||||
|
{
|
||||||
|
return [self namespaceWithName: @"xsi"
|
||||||
|
stringValue: @"http://www.w3.org/2001/XMLSchema-instance"];
|
||||||
|
}
|
||||||
|
if ([name isEqualToString: @"fn"])
|
||||||
|
{
|
||||||
|
return [self namespaceWithName: @"fn"
|
||||||
|
stringValue: @"http://www.w3.org/2003/11/xpath-functions"];
|
||||||
|
}
|
||||||
|
if ([name isEqualToString: @"local"])
|
||||||
|
{
|
||||||
|
return [self namespaceWithName: @"local"
|
||||||
|
stringValue: @"http://www.w3.org/2003/11/xpath-local-functions"];
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSString*) prefixForName: (NSString*)name
|
+ (NSString*) prefixForName: (NSString*)name
|
||||||
{
|
{
|
||||||
return [self notImplemented: _cmd];
|
const xmlChar *xmlName = XMLSTRING(name);
|
||||||
|
xmlChar *prefix = NULL;
|
||||||
|
|
||||||
|
if (NULL == xmlName)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
xmlSplitQName2(xmlName, &prefix);
|
||||||
|
|
||||||
|
if (NULL == prefix)
|
||||||
|
{
|
||||||
|
return @"";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return StringFromXMLStringPtr(prefix);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id) processingInstructionWithName: (NSString*)name
|
+ (id) processingInstructionWithName: (NSString*)name
|
||||||
|
@ -722,29 +852,10 @@ NSArray *execute_xpath(NSXMLNode *node,
|
||||||
return [self notImplemented: _cmd]; // FIXME ... generate from libxml
|
return [self notImplemented: _cmd]; // FIXME ... generate from libxml
|
||||||
}
|
}
|
||||||
|
|
||||||
- (xmlNodePtr) _childNodeAtIndex: (NSUInteger)index
|
|
||||||
{
|
|
||||||
NSUInteger count = 0;
|
|
||||||
xmlNodePtr node = (xmlNodePtr)(internal->node);
|
|
||||||
xmlNodePtr children = node->children;
|
|
||||||
if (!children)
|
|
||||||
return NULL; // the Cocoa docs say it returns nil if there are no children
|
|
||||||
|
|
||||||
for (children = node->children; children != NULL && count != index; children = children->next)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count != index)
|
|
||||||
[NSException raise: NSRangeException format: @"child index too large"];
|
|
||||||
|
|
||||||
return children;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSXMLNode*) childAtIndex: (NSUInteger)index
|
- (NSXMLNode*) childAtIndex: (NSUInteger)index
|
||||||
{
|
{
|
||||||
xmlNodePtr childNode = [self _childNodeAtIndex:index];
|
xmlNodePtr childNode = [self _childNodeAtIndex:index];
|
||||||
return (NSXMLNode *)[NSXMLNode _objectForNode: childNode];
|
return [NSXMLNode _objectForNode: childNode];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSUInteger) childCount
|
- (NSUInteger) childCount
|
||||||
|
@ -764,6 +875,7 @@ NSArray *execute_xpath(NSXMLNode *node,
|
||||||
- (NSArray*) children
|
- (NSArray*) children
|
||||||
{
|
{
|
||||||
NSMutableArray *childrenArray = nil;
|
NSMutableArray *childrenArray = nil;
|
||||||
|
|
||||||
if (NSXMLInvalidKind == internal->kind)
|
if (NSXMLInvalidKind == internal->kind)
|
||||||
{
|
{
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -788,79 +900,6 @@ NSArray *execute_xpath(NSXMLNode *node,
|
||||||
return childrenArray;
|
return childrenArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) _insertChild: (NSXMLNode*)child atIndex: (NSUInteger)index
|
|
||||||
{
|
|
||||||
// this private method provides the common insertion implementation used by NSXMLElement and NSXMLDocument
|
|
||||||
|
|
||||||
// Get all of the nodes...
|
|
||||||
xmlNodePtr parentNode = MY_NODE; // we are the parent
|
|
||||||
xmlNodePtr childNode = ((xmlNodePtr)[child _node]);
|
|
||||||
xmlNodePtr curNode = [self _childNodeAtIndex: index];
|
|
||||||
BOOL mergeTextNodes = NO; // is there a defined option for this?
|
|
||||||
|
|
||||||
if (mergeTextNodes || childNode->type == XML_ATTRIBUTE_NODE)
|
|
||||||
{
|
|
||||||
// this uses the built-in libxml functions which merge adjacent text nodes
|
|
||||||
xmlNodePtr addedNode = NULL;
|
|
||||||
//curNode = ((xmlNodePtr)[cur _node]);
|
|
||||||
|
|
||||||
if (curNode == NULL) //(0 == childCount || index == childCount)
|
|
||||||
{
|
|
||||||
addedNode = xmlAddChild(parentNode, childNode);
|
|
||||||
}
|
|
||||||
else //if(index < childCount)
|
|
||||||
{
|
|
||||||
addedNode = xmlAddPrevSibling(curNode, childNode);
|
|
||||||
}
|
|
||||||
if (addedNode != childNode)
|
|
||||||
{
|
|
||||||
[child _setNode:NULL];
|
|
||||||
child = [NSXMLNode _objectForNode:addedNode];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// here we avoid merging adjacent text nodes by linking the new node in "by hand"
|
|
||||||
childNode->parent = parentNode;
|
|
||||||
if (curNode)
|
|
||||||
{
|
|
||||||
// insert childNode before an existing node curNode
|
|
||||||
xmlNodePtr prevNode = curNode->prev;
|
|
||||||
curNode->prev = childNode;
|
|
||||||
childNode->next = curNode;
|
|
||||||
if (prevNode)
|
|
||||||
{
|
|
||||||
childNode->prev = prevNode;
|
|
||||||
prevNode->next = childNode;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// in this case, this is the new "first child", so update our parent to point to it
|
|
||||||
parentNode->children = childNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// not inserting before an existing node... add as new "last child"
|
|
||||||
xmlNodePtr formerLastChild = parentNode->last;
|
|
||||||
if (formerLastChild)
|
|
||||||
{
|
|
||||||
formerLastChild->next = childNode;
|
|
||||||
childNode->prev = formerLastChild;
|
|
||||||
parentNode->last = childNode;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// no former children -- this is the first
|
|
||||||
parentNode->children = childNode;
|
|
||||||
parentNode->last = childNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[self _addSubNode:child];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id) copyWithZone: (NSZone*)zone
|
- (id) copyWithZone: (NSZone*)zone
|
||||||
{
|
{
|
||||||
id c = [[self class] allocWithZone: zone];
|
id c = [[self class] allocWithZone: zone];
|
||||||
|
@ -881,58 +920,12 @@ NSArray *execute_xpath(NSXMLNode *node,
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** these methods should go away now
|
|
||||||
- (void) recordExternalRetain:(int)count
|
|
||||||
{
|
|
||||||
id parent = [self parent];
|
|
||||||
if (parent)
|
|
||||||
[parent recordExternalRetain:count];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (count > 0 && internal->externalRetains == 0)
|
|
||||||
{
|
|
||||||
[super retain]; // the top of the tree retains itself whenever there are external retains anywhere
|
|
||||||
if ([self retainCount] == 2)
|
|
||||||
{
|
|
||||||
internal->externalRetains++;
|
|
||||||
NSLog(@"ADDED TRICKY EXTRA COUNT in %@ now: %d subNodes(OFF):%d", self, internal->externalRetains, [self verifyExternalRetains]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal->externalRetains += count;
|
|
||||||
NSLog(@"recordExternalRetain in %@ now: %d subNodes:%d", self, internal->externalRetains, [self verifyExternalRetains]);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) releaseExternalRetain:(int)count
|
|
||||||
{
|
|
||||||
id parent = [self parent];
|
|
||||||
internal->externalRetains -= count;
|
|
||||||
if (internal->externalRetains <0)
|
|
||||||
NSLog(@"ExternalRetains going NEGATIVE: %d in %@", internal->externalRetains - count, self);
|
|
||||||
|
|
||||||
NSLog(@"releaseExternalRetain in %@ now: %d", self, internal->externalRetains);
|
|
||||||
if (parent)
|
|
||||||
[parent releaseExternalRetain:count];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// check for tricky condition where our only "external" retain is from ourself and is about to go away
|
|
||||||
if (count > 0 && internal->externalRetains == 1 && [self retainCount] == 2)
|
|
||||||
{
|
|
||||||
internal->externalRetains--;
|
|
||||||
NSLog(@"RELEASING TRICKY EXTRA RETAIN in %@ now: %d", self, internal->externalRetains);
|
|
||||||
}
|
|
||||||
if (count > 0 && internal->externalRetains == 0)
|
|
||||||
[super release]; // the top of the tree retains itself whenever there are external retains anywhere
|
|
||||||
}
|
|
||||||
}
|
|
||||||
**/
|
|
||||||
|
|
||||||
- (id) retain
|
- (id) retain
|
||||||
{
|
{
|
||||||
[super retain]; // do this first
|
[super retain]; // do this first
|
||||||
if ([self retainCount] == 2)
|
if ([self retainCount] == 2)
|
||||||
{
|
{
|
||||||
[self _updateExternalRetains]; //[self recordExternalRetain:1];
|
[self _updateExternalRetains];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -942,7 +935,7 @@ NSLog(@"RELEASING TRICKY EXTRA RETAIN in %@ now: %d", self, internal->externalRe
|
||||||
if ([self retainCount] == 2)
|
if ([self retainCount] == 2)
|
||||||
{
|
{
|
||||||
[super release];
|
[super release];
|
||||||
[self _updateExternalRetains]; //[self releaseExternalRetain:1];
|
[self _updateExternalRetains];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
[super release];
|
[super release];
|
||||||
|
@ -975,12 +968,12 @@ NSLog(@"RELEASING TRICKY EXTRA RETAIN in %@ now: %d", self, internal->externalRe
|
||||||
xmlNodePtr node = (xmlNodePtr)(internal->node);
|
xmlNodePtr node = (xmlNodePtr)(internal->node);
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
int extraRetains = 0;
|
|
||||||
xmlNodePtr parentNode = node->parent;
|
xmlNodePtr parentNode = node->parent;
|
||||||
NSXMLNode *parent = (parentNode ? parentNode->_private : nil); // get our parent object if it exists
|
NSXMLNode *parent = (parentNode ? parentNode->_private : nil); // get our parent object if it exists
|
||||||
xmlUnlinkNode(node); // separate our node from its parent and siblings
|
xmlUnlinkNode(node); // separate our node from its parent and siblings
|
||||||
if (parent)
|
if (parent)
|
||||||
{
|
{
|
||||||
|
int extraRetains = 0;
|
||||||
// transfer extra retains of this branch from our parent to ourself
|
// transfer extra retains of this branch from our parent to ourself
|
||||||
extraRetains = internal->externalRetains; //[self verifyExternalRetains];
|
extraRetains = internal->externalRetains; //[self verifyExternalRetains];
|
||||||
if (extraRetains)
|
if (extraRetains)
|
||||||
|
@ -1003,7 +996,7 @@ NSLog(@"RELEASING TRICKY EXTRA RETAIN in %@ now: %d", self, internal->externalRe
|
||||||
|
|
||||||
- (NSUInteger) hash
|
- (NSUInteger) hash
|
||||||
{
|
{
|
||||||
return [StringFromXMLStringPtr(MY_NODE->name) hash];
|
return [[self name] hash];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSUInteger) index
|
- (NSUInteger) index
|
||||||
|
@ -1025,8 +1018,7 @@ NSLog(@"RELEASING TRICKY EXTRA RETAIN in %@ now: %d", self, internal->externalRe
|
||||||
|
|
||||||
- (id) initWithKind: (NSXMLNodeKind) kind
|
- (id) initWithKind: (NSXMLNodeKind) kind
|
||||||
{
|
{
|
||||||
self = [self initWithKind: kind options: 0];
|
return [self initWithKind: kind options: 0];
|
||||||
return self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithKind: (NSXMLNodeKind)kind options: (NSUInteger)theOptions
|
- (id) initWithKind: (NSXMLNodeKind)kind options: (NSUInteger)theOptions
|
||||||
|
@ -1186,7 +1178,7 @@ NSLog(@"RELEASING TRICKY EXTRA RETAIN in %@ now: %d", self, internal->externalRe
|
||||||
|
|
||||||
- (NSString*) localName
|
- (NSString*) localName
|
||||||
{
|
{
|
||||||
return [self notImplemented: _cmd]; // FIXME ... fetch from libxml
|
return [[self class] localNameForName: [self name]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*) name
|
- (NSString*) name
|
||||||
|
@ -1209,7 +1201,7 @@ NSLog(@"RELEASING TRICKY EXTRA RETAIN in %@ now: %d", self, internal->externalRe
|
||||||
NSUInteger theIndex = 0;
|
NSUInteger theIndex = 0;
|
||||||
if (NO == forward)
|
if (NO == forward)
|
||||||
{
|
{
|
||||||
theIndex = ([self childCount]) - 1;
|
theIndex = [self childCount] - 1;
|
||||||
}
|
}
|
||||||
candidate = [[self children] objectAtIndex: theIndex];
|
candidate = [[self children] objectAtIndex: theIndex];
|
||||||
}
|
}
|
||||||
|
@ -1287,7 +1279,7 @@ NSLog(@"RELEASING TRICKY EXTRA RETAIN in %@ now: %d", self, internal->externalRe
|
||||||
|
|
||||||
- (NSString*) prefix
|
- (NSString*) prefix
|
||||||
{
|
{
|
||||||
return [self notImplemented: _cmd]; // FIXME ... fetch from libxml
|
return [[self class] prefixForName: [self name]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSXMLNode*) previousNode
|
- (NSXMLNode*) previousNode
|
||||||
|
@ -1329,6 +1321,7 @@ NSLog(@"RELEASING TRICKY EXTRA RETAIN in %@ now: %d", self, internal->externalRe
|
||||||
*/
|
*/
|
||||||
|
|
||||||
result = StringFromXMLStringPtr(content);
|
result = StringFromXMLStringPtr(content);
|
||||||
|
xmlFree(content);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -1342,30 +1335,6 @@ NSLog(@"RELEASING TRICKY EXTRA RETAIN in %@ now: %d", self, internal->externalRe
|
||||||
return internal->URI; // FIXME ... fetch from libxml
|
return internal->URI; // FIXME ... fetch from libxml
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString*) XMLString
|
|
||||||
{
|
|
||||||
return [self XMLStringWithOptions: 0];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString*) XMLStringWithOptions: (NSUInteger)options
|
|
||||||
{
|
|
||||||
NSString *string = nil;
|
|
||||||
xmlNodePtr node = (xmlNodePtr)[self _node];
|
|
||||||
xmlChar *buf = NULL;
|
|
||||||
xmlDocPtr doc = node->doc;
|
|
||||||
xmlBufferPtr buffer = xmlBufferCreate(); //NULL;
|
|
||||||
int error = 0;
|
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
error = xmlNodeDump(buffer, doc, node, 1, 1);
|
|
||||||
buf = buffer->content;
|
|
||||||
len = buffer->use;
|
|
||||||
string = StringFromXMLString(buf,len);
|
|
||||||
xmlBufferFree(buffer);
|
|
||||||
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) setObjectValue: (id)value
|
- (void) setObjectValue: (id)value
|
||||||
{
|
{
|
||||||
if(nil == value)
|
if(nil == value)
|
||||||
|
@ -1390,14 +1359,6 @@ NSLog(@"RELEASING TRICKY EXTRA RETAIN in %@ now: %d", self, internal->externalRe
|
||||||
[self setStringValue: string resolvingEntities: NO];
|
[self setStringValue: string resolvingEntities: NO];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setURI: (NSString*)URI
|
|
||||||
{
|
|
||||||
if (NSXMLInvalidKind != internal->kind)
|
|
||||||
{
|
|
||||||
ASSIGNCOPY(internal->URI, URI);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) setStringValue: (NSString*)string resolvingEntities: (BOOL)resolve
|
- (void) setStringValue: (NSString*)string resolvingEntities: (BOOL)resolve
|
||||||
{
|
{
|
||||||
xmlNodePtr node = MY_NODE;
|
xmlNodePtr node = MY_NODE;
|
||||||
|
@ -1418,6 +1379,38 @@ NSLog(@"RELEASING TRICKY EXTRA RETAIN in %@ now: %d", self, internal->externalRe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setURI: (NSString*)URI
|
||||||
|
{
|
||||||
|
if (NSXMLInvalidKind != internal->kind)
|
||||||
|
{
|
||||||
|
ASSIGNCOPY(internal->URI, URI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString*) XMLString
|
||||||
|
{
|
||||||
|
return [self XMLStringWithOptions: 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString*) XMLStringWithOptions: (NSUInteger)options
|
||||||
|
{
|
||||||
|
NSString *string = nil;
|
||||||
|
xmlNodePtr node = (xmlNodePtr)[self _node];
|
||||||
|
xmlChar *buf = NULL;
|
||||||
|
xmlDocPtr doc = node->doc;
|
||||||
|
xmlBufferPtr buffer = xmlBufferCreate(); //NULL;
|
||||||
|
int error = 0;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
error = xmlNodeDump(buffer, doc, node, 1, 1);
|
||||||
|
buf = buffer->content;
|
||||||
|
len = buffer->use;
|
||||||
|
string = StringFromXMLString(buf,len);
|
||||||
|
xmlBufferFree(buffer);
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSString*) XPath
|
- (NSString*) XPath
|
||||||
{
|
{
|
||||||
xmlNodePtr node = MY_NODE;
|
xmlNodePtr node = MY_NODE;
|
||||||
|
|
Loading…
Reference in a new issue