mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 00:41:02 +00:00
added _insertChild:atIndex: private method to replicate Cocoa behavior of allowing adjacent text nodes
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/branches/nsxml_using_libxml2@34684 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
67effbde5f
commit
a7a674de22
4 changed files with 98 additions and 50 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2012-01-31 Doug Simons <doug.simons@testplant.com>
|
||||
|
||||
* Source/NSXMLDocument.m
|
||||
* Source/NSXMLElement.m
|
||||
* Source/NSXMLNode.m (-insertChild:atIndex:): Implement our own
|
||||
_insertChild:atIndex: method to link a child in by hand. This
|
||||
avoids the built-in libxml functions' behavior of always merging
|
||||
adjacent text nodes as they are added, which Cocoa doesn't do.
|
||||
Next we need to implement -normalizeAdjacentTextNodesPreservingCDATA:.
|
||||
|
||||
2012-01-31 17:57-EST Gregory John Casamento <greg.casamento@gmail.com>
|
||||
|
||||
* Source/NSXMLDocument.m: Minor corrections in
|
||||
|
|
|
@ -42,6 +42,7 @@ extern void clearPrivatePointers(xmlNodePtr aNode);
|
|||
+ (NSXMLNode *) _objectForNode: (xmlNodePtr)node;
|
||||
- (void) _addSubNode:(NSXMLNode *)subNode;
|
||||
- (void) _removeSubNode:(NSXMLNode *)subNode;
|
||||
- (void) _insertChild: (NSXMLNode*)child atIndex: (NSUInteger)index;
|
||||
@end
|
||||
|
||||
@implementation NSXMLDocument
|
||||
|
@ -288,15 +289,11 @@ extern void clearPrivatePointers(xmlNodePtr aNode);
|
|||
- (void) insertChild: (NSXMLNode*)child atIndex: (NSUInteger)index
|
||||
{
|
||||
NSXMLNodeKind kind = [child kind];
|
||||
NSXMLNode *cur = nil;
|
||||
xmlNodePtr curNode = NULL;
|
||||
xmlNodePtr thisNode = (xmlNodePtr)[self _node];
|
||||
xmlNodePtr childNode = (xmlNodePtr)[child _node];
|
||||
NSUInteger childCount = [self childCount];
|
||||
|
||||
// Check to make sure this is a valid addition...
|
||||
NSAssert(nil != child, NSInvalidArgumentException);
|
||||
NSAssert(index <= [self childCount], NSInvalidArgumentException);
|
||||
NSAssert(index <= childCount, NSInvalidArgumentException);
|
||||
NSAssert(nil == [child parent], NSInvalidArgumentException);
|
||||
kind = [child kind];
|
||||
NSAssert(NSXMLAttributeKind != kind, NSInvalidArgumentException);
|
||||
|
@ -308,22 +305,7 @@ extern void clearPrivatePointers(xmlNodePtr aNode);
|
|||
NSAssert(NSXMLNamespaceKind != kind, NSInvalidArgumentException);
|
||||
NSAssert(NSXMLNotationDeclarationKind != kind, NSInvalidArgumentException);
|
||||
|
||||
|
||||
// Get all of the nodes...
|
||||
childNode = ((xmlNodePtr)[child _node]);
|
||||
cur = [self childAtIndex: index];
|
||||
curNode = ((xmlNodePtr)[cur _node]);
|
||||
|
||||
if(0 == childCount || index == childCount)
|
||||
{
|
||||
xmlAddChild(thisNode, childNode);
|
||||
}
|
||||
else if(index < childCount)
|
||||
{
|
||||
xmlAddNextSibling(curNode, childNode);
|
||||
}
|
||||
|
||||
[self _addSubNode:child];
|
||||
[self _insertChild:child atIndex:index];
|
||||
}
|
||||
|
||||
- (void) insertChildren: (NSArray*)children atIndex: (NSUInteger)index
|
||||
|
|
|
@ -39,6 +39,7 @@ extern void clearPrivatePointers(xmlNodePtr aNode);
|
|||
- (void) _addSubNode:(NSXMLNode *)subNode;
|
||||
- (void) _removeSubNode:(NSXMLNode *)subNode;
|
||||
- (id) _initWithNode:(xmlNodePtr)node kind:(NSXMLNodeKind)kind;
|
||||
- (void) _insertChild: (NSXMLNode*)child atIndex: (NSUInteger)index;
|
||||
@end
|
||||
|
||||
@implementation NSXMLElement
|
||||
|
@ -333,12 +334,7 @@ extern void clearPrivatePointers(xmlNodePtr aNode);
|
|||
- (void) insertChild: (NSXMLNode*)child atIndex: (NSUInteger)index
|
||||
{
|
||||
NSXMLNodeKind kind = [child kind];
|
||||
NSXMLNode *cur = nil;
|
||||
xmlNodePtr curNode = NULL;
|
||||
xmlNodePtr thisNode = (xmlNodePtr)[self _node];
|
||||
xmlNodePtr childNode = (xmlNodePtr)[child _node];
|
||||
NSUInteger childCount = [self childCount];
|
||||
xmlNodePtr addedNode = NULL;
|
||||
|
||||
// Check to make sure this is a valid addition...
|
||||
NSAssert(nil != child, NSInvalidArgumentException);
|
||||
|
@ -353,26 +349,7 @@ extern void clearPrivatePointers(xmlNodePtr aNode);
|
|||
NSAssert(NSXMLNamespaceKind != kind, NSInvalidArgumentException);
|
||||
NSAssert(NSXMLNotationDeclarationKind != kind, NSInvalidArgumentException);
|
||||
|
||||
// Get all of the nodes...
|
||||
childNode = ((xmlNodePtr)[child _node]);
|
||||
cur = [self childAtIndex: index];
|
||||
curNode = ((xmlNodePtr)[cur _node]);
|
||||
|
||||
if(0 == childCount || index == childCount)
|
||||
{
|
||||
addedNode = xmlAddChild(thisNode, childNode);
|
||||
}
|
||||
else if(index < childCount)
|
||||
{
|
||||
addedNode = xmlAddPrevSibling(curNode, childNode);
|
||||
}
|
||||
if (addedNode != childNode)
|
||||
{
|
||||
[child _setNode:NULL];
|
||||
child = [NSXMLNode _objectForNode:addedNode];
|
||||
}
|
||||
|
||||
[self _addSubNode:child];
|
||||
[self _insertChild:child atIndex:index];
|
||||
}
|
||||
|
||||
- (void) insertChildren: (NSArray*)children atIndex: (NSUInteger)index
|
||||
|
|
|
@ -555,15 +555,15 @@ NSArray *execute_xpath(NSXMLNode *node,
|
|||
return [self notImplemented: _cmd]; // FIXME ... generate from libxml
|
||||
}
|
||||
|
||||
- (NSXMLNode*) childAtIndex: (NSUInteger)index
|
||||
- (xmlNodePtr) _childNodeAtIndex: (NSUInteger)index
|
||||
{
|
||||
NSUInteger count = 0;
|
||||
xmlNodePtr node = (xmlNodePtr)(internal->node);
|
||||
xmlNodePtr children = node->children;
|
||||
if (!children)
|
||||
return nil; // the Cocoa docs say it returns nil if there are no children
|
||||
return NULL; // the Cocoa docs say it returns nil if there are no children
|
||||
|
||||
for (children = node->children; children && count != index; children = children->next)
|
||||
for (children = node->children; children != NULL && count != index; children = children->next)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
@ -571,7 +571,13 @@ NSArray *execute_xpath(NSXMLNode *node,
|
|||
if (count != index)
|
||||
[NSException raise: NSRangeException format: @"child index too large"];
|
||||
|
||||
return (NSXMLNode *)[NSXMLNode _objectForNode: children];
|
||||
return children;
|
||||
}
|
||||
|
||||
- (NSXMLNode*) childAtIndex: (NSUInteger)index
|
||||
{
|
||||
xmlNodePtr childNode = [self _childNodeAtIndex:index];
|
||||
return (NSXMLNode *)[NSXMLNode _objectForNode: childNode];
|
||||
}
|
||||
|
||||
- (NSUInteger) childCount
|
||||
|
@ -615,6 +621,79 @@ NSArray *execute_xpath(NSXMLNode *node,
|
|||
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 c = [[self class] allocWithZone: zone];
|
||||
|
|
Loading…
Reference in a new issue