2009-02-09 16:16:11 +00:00
|
|
|
/* Implementation for NSXMLNode for GNUStep
|
|
|
|
Copyright (C) 2008 Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
Written by: Richard Frith-Macdonald <rfm@gnu.org>
|
|
|
|
Created: September 2008
|
|
|
|
|
|
|
|
This file is part of the GNUstep Base Library.
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Lesser General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 3 of the License, or (at your option) any later version.
|
2011-10-01 18:43:29 +00:00
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
License along with this library; if not, write to the Free
|
|
|
|
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02111 USA.
|
|
|
|
*/
|
|
|
|
|
2010-02-19 08:12:46 +00:00
|
|
|
#import "common.h"
|
|
|
|
|
2012-01-04 09:20:32 +00:00
|
|
|
#define GSInternal NSXMLNodeInternal
|
2012-01-05 20:40:12 +00:00
|
|
|
#import "NSXMLPrivate.h"
|
|
|
|
#import "GSInternal.h"
|
2012-01-04 09:20:32 +00:00
|
|
|
GS_PRIVATE_INTERNAL(NSXMLNode)
|
2011-10-01 18:43:29 +00:00
|
|
|
|
2012-01-11 01:05:35 +00:00
|
|
|
// Private methods to manage libxml pointers...
|
|
|
|
@interface NSXMLNode (Private)
|
|
|
|
- (void *) _node;
|
|
|
|
- (void) _setNode: (void *)_anode;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation NSXMLNode (Private)
|
|
|
|
- (void *) _node
|
|
|
|
{
|
|
|
|
return internal->node;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) _setNode: (void *)_anode
|
|
|
|
{
|
|
|
|
internal->node = _anode;
|
|
|
|
}
|
|
|
|
@end
|
2011-10-17 10:24:07 +00:00
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
@implementation NSXMLNode
|
|
|
|
|
|
|
|
+ (id) attributeWithName: (NSString*)name
|
|
|
|
stringValue: (NSString*)stringValue
|
|
|
|
{
|
|
|
|
NSXMLNode *n;
|
2012-01-11 17:54:44 +00:00
|
|
|
xmlAttrPtr node;
|
2009-02-09 16:16:11 +00:00
|
|
|
|
|
|
|
n = [[[self alloc] initWithKind: NSXMLAttributeKind] autorelease];
|
|
|
|
[n setStringValue: stringValue];
|
2011-12-30 21:40:12 +00:00
|
|
|
[n setName: name];
|
2012-01-11 01:05:35 +00:00
|
|
|
node = xmlNewProp(NULL,
|
|
|
|
(xmlChar *)[name UTF8String],
|
|
|
|
(xmlChar *)[stringValue UTF8String]);
|
2012-01-11 17:54:44 +00:00
|
|
|
[n _setNode: node];
|
2012-01-11 01:05:35 +00:00
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (id) attributeWithName: (NSString*)name
|
|
|
|
URI: (NSString*)URI
|
|
|
|
stringValue: (NSString*)stringValue
|
|
|
|
{
|
|
|
|
NSXMLNode *n;
|
2012-01-11 17:54:44 +00:00
|
|
|
xmlAttrPtr node = xmlNewProp(NULL,
|
|
|
|
XMLSTRING(name),
|
|
|
|
XMLSTRING(stringValue));
|
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
n = [[[self alloc] initWithKind: NSXMLAttributeKind] autorelease];
|
|
|
|
[n setURI: URI];
|
|
|
|
[n setStringValue: stringValue];
|
2011-12-30 21:40:12 +00:00
|
|
|
[n setName: name];
|
2012-01-11 17:54:44 +00:00
|
|
|
[n _setNode: node];
|
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (id) commentWithStringValue: (NSString*)stringValue
|
|
|
|
{
|
|
|
|
NSXMLNode *n;
|
2012-01-11 17:54:44 +00:00
|
|
|
xmlNodePtr node = xmlNewComment(XMLSTRING(stringValue));
|
2009-02-09 16:16:11 +00:00
|
|
|
|
|
|
|
n = [[[self alloc] initWithKind: NSXMLCommentKind] autorelease];
|
|
|
|
[n setStringValue: stringValue];
|
2012-01-11 17:54:44 +00:00
|
|
|
[n _setNode: node];
|
2012-01-11 01:05:35 +00:00
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (id) DTDNodeWithXMLString: (NSString*)string
|
|
|
|
{
|
|
|
|
NSXMLNode *n;
|
|
|
|
|
|
|
|
n = [[[self alloc] initWithKind: NSXMLDTDKind] autorelease];
|
|
|
|
[n setStringValue: string];
|
2012-01-11 01:05:35 +00:00
|
|
|
|
|
|
|
// internal->node = xmlNewDtd(NULL,NULL,NULL); // TODO: Parse the string and get the info to create this...
|
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (id) document
|
|
|
|
{
|
|
|
|
NSXMLNode *n;
|
|
|
|
|
|
|
|
n = [[[NSXMLDocument alloc] initWithKind:NSXMLDocumentKind] autorelease];
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (id) documentWithRootElement: (NSXMLElement*)element
|
|
|
|
{
|
|
|
|
NSXMLDocument *d;
|
|
|
|
|
|
|
|
d = [NSXMLDocument alloc];
|
|
|
|
d = [[d initWithRootElement: element] autorelease];
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (id) elementWithName: (NSString*)name
|
|
|
|
{
|
|
|
|
NSXMLNode *n;
|
|
|
|
|
|
|
|
n = [[[NSXMLElement alloc] initWithName: name] autorelease];
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (id) elementWithName: (NSString*)name
|
|
|
|
children: (NSArray*)children
|
|
|
|
attributes: (NSArray*)attributes
|
|
|
|
{
|
|
|
|
NSXMLElement *e = [self elementWithName: name];
|
|
|
|
|
|
|
|
[e insertChildren: children atIndex: 0];
|
|
|
|
[e setAttributes: attributes];
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (id) elementWithName: (NSString*)name
|
|
|
|
URI: (NSString*)URI
|
|
|
|
{
|
|
|
|
NSXMLNode *n;
|
|
|
|
|
|
|
|
n = [[[NSXMLElement alloc] initWithName: name URI: URI] autorelease];
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (id) elementWithName: (NSString*)name
|
|
|
|
stringValue: (NSString*)string
|
|
|
|
{
|
|
|
|
NSXMLElement *e;
|
|
|
|
NSXMLNode *t;
|
|
|
|
|
2011-10-01 18:43:29 +00:00
|
|
|
e = [self elementWithName: name];
|
2009-02-09 16:16:11 +00:00
|
|
|
t = [[self alloc] initWithKind: NSXMLTextKind];
|
|
|
|
[t setStringValue: string];
|
|
|
|
[e addChild: t];
|
|
|
|
[t release];
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSString*) localNameForName: (NSString*)name
|
|
|
|
{
|
|
|
|
return [self notImplemented: _cmd];
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (id) namespaceWithName: (NSString*)name
|
|
|
|
stringValue: (NSString*)stringValue
|
|
|
|
{
|
|
|
|
NSXMLNode *n;
|
|
|
|
|
|
|
|
n = [[[self alloc] initWithKind: NSXMLNamespaceKind] autorelease];
|
|
|
|
[n setStringValue: stringValue];
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSXMLNode*) predefinedNamespaceForPrefix: (NSString*)name
|
|
|
|
{
|
|
|
|
return [self notImplemented: _cmd];
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSString*) prefixForName: (NSString*)name
|
|
|
|
{
|
|
|
|
return [self notImplemented: _cmd];
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (id) processingInstructionWithName: (NSString*)name
|
|
|
|
stringValue: (NSString*)stringValue
|
|
|
|
{
|
|
|
|
NSXMLNode *n;
|
|
|
|
|
|
|
|
n = [[[self alloc] initWithKind: NSXMLProcessingInstructionKind] autorelease];
|
|
|
|
[n setStringValue: stringValue];
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (id) textWithStringValue: (NSString*)stringValue
|
|
|
|
{
|
|
|
|
NSXMLNode *n;
|
|
|
|
|
|
|
|
n = [[[self alloc] initWithKind: NSXMLTextKind] autorelease];
|
|
|
|
[n setStringValue: stringValue];
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString*) canonicalXMLStringPreservingComments: (BOOL)comments
|
|
|
|
{
|
|
|
|
return [self notImplemented: _cmd]; // FIXME ... generate from libxml
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSXMLNode*) childAtIndex: (NSUInteger)index
|
|
|
|
{
|
2012-01-04 09:20:32 +00:00
|
|
|
return [internal->children objectAtIndex: index];
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSUInteger) childCount
|
|
|
|
{
|
2012-01-04 09:20:32 +00:00
|
|
|
return internal->childCount;
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
2012-01-06 12:22:30 +00:00
|
|
|
- (NSArray*) children
|
2009-02-09 16:16:11 +00:00
|
|
|
{
|
2012-01-04 09:20:32 +00:00
|
|
|
return internal->children;
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (id) copyWithZone: (NSZone*)zone
|
|
|
|
{
|
2012-01-06 02:43:26 +00:00
|
|
|
id c = [[self class] allocWithZone: zone];
|
2012-01-04 12:41:45 +00:00
|
|
|
|
|
|
|
c = [c initWithKind: internal->kind options: internal->options];
|
|
|
|
[c setName: [self name]];
|
|
|
|
[c setURI: [self URI]];
|
|
|
|
[c setObjectValue: [self objectValue]];
|
|
|
|
[c setStringValue: [self stringValue]];
|
2012-01-06 02:43:26 +00:00
|
|
|
|
2012-01-04 12:41:45 +00:00
|
|
|
return c;
|
2012-01-06 12:48:49 +00:00
|
|
|
}
|
2009-02-09 16:16:11 +00:00
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
{
|
2012-01-04 12:41:45 +00:00
|
|
|
if (GS_EXISTS_INTERNAL)
|
|
|
|
{
|
|
|
|
[self detach];
|
|
|
|
[internal->name release];
|
|
|
|
[internal->URI release];
|
|
|
|
[internal->children release];
|
|
|
|
[internal->objectValue release];
|
|
|
|
[internal->stringValue release];
|
|
|
|
GS_DESTROY_INTERNAL(NSXMLNode);
|
|
|
|
}
|
2009-02-09 16:16:11 +00:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) detach
|
|
|
|
{
|
2012-01-11 01:05:35 +00:00
|
|
|
if (internal->parent != nil)
|
|
|
|
{
|
|
|
|
[(NSXMLElement*)internal->parent removeChildAtIndex: internal->index];
|
|
|
|
internal->parent = nil;
|
|
|
|
}
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
2012-01-06 12:22:30 +00:00
|
|
|
- (NSUInteger) hash
|
|
|
|
{
|
|
|
|
return [internal->name hash];
|
|
|
|
}
|
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
- (NSUInteger) index
|
|
|
|
{
|
2012-01-11 01:05:35 +00:00
|
|
|
return internal->index;
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
2011-10-01 18:43:29 +00:00
|
|
|
- (id) init
|
|
|
|
{
|
|
|
|
return [self initWithKind: NSXMLInvalidKind];
|
|
|
|
}
|
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
- (id) initWithKind:(NSXMLNodeKind) kind
|
|
|
|
{
|
|
|
|
self = [self initWithKind: kind options: 0];
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2011-10-01 18:43:29 +00:00
|
|
|
- (id) initWithKind: (NSXMLNodeKind)kind options: (NSUInteger)theOptions
|
2009-02-09 16:16:11 +00:00
|
|
|
{
|
2011-10-01 18:43:29 +00:00
|
|
|
Class theSubclass = [NSXMLNode class];
|
2012-01-04 12:41:45 +00:00
|
|
|
|
2011-10-01 18:43:29 +00:00
|
|
|
if (nil == (self = [super init]))
|
2012-01-01 07:38:53 +00:00
|
|
|
{
|
|
|
|
return nil;
|
|
|
|
}
|
2011-10-01 18:43:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We find the correct subclass for specific node kinds:
|
|
|
|
*/
|
|
|
|
switch (kind)
|
|
|
|
{
|
2012-01-01 07:38:53 +00:00
|
|
|
case NSXMLDocumentKind:
|
|
|
|
theSubclass = [NSXMLDocument class];
|
|
|
|
break;
|
2012-01-04 12:41:45 +00:00
|
|
|
|
2012-01-01 07:38:53 +00:00
|
|
|
case NSXMLElementKind:
|
|
|
|
theSubclass = [NSXMLElement class];
|
|
|
|
break;
|
2012-01-04 12:41:45 +00:00
|
|
|
|
2012-01-01 07:38:53 +00:00
|
|
|
case NSXMLDTDKind:
|
|
|
|
theSubclass = [NSXMLDTD class];
|
|
|
|
break;
|
2012-01-04 12:41:45 +00:00
|
|
|
|
2012-01-01 07:38:53 +00:00
|
|
|
case NSXMLEntityDeclarationKind:
|
|
|
|
case NSXMLElementDeclarationKind:
|
|
|
|
case NSXMLNotationDeclarationKind:
|
|
|
|
theSubclass = [NSXMLDTDNode class];
|
|
|
|
break;
|
2012-01-04 12:41:45 +00:00
|
|
|
|
2012-01-01 07:38:53 +00:00
|
|
|
default:
|
|
|
|
break;
|
2011-10-01 18:43:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check whether we are already initializing an instance of the given
|
|
|
|
* subclass. If we are not, release ourselves and allocate a subclass instance
|
|
|
|
* instead.
|
|
|
|
*/
|
|
|
|
if (NO == [self isKindOfClass: theSubclass])
|
2012-01-01 07:38:53 +00:00
|
|
|
{
|
|
|
|
[self release];
|
|
|
|
return [[theSubclass alloc] initWithKind: kind
|
|
|
|
options: theOptions];
|
|
|
|
}
|
2011-10-01 18:43:29 +00:00
|
|
|
|
2012-01-04 12:41:45 +00:00
|
|
|
/* Create holder for internal instance variables if needed.
|
2011-10-01 18:43:29 +00:00
|
|
|
*/
|
2012-01-04 12:41:45 +00:00
|
|
|
GS_CREATE_INTERNAL(NSXMLNode)
|
2011-10-01 18:43:29 +00:00
|
|
|
|
2012-01-04 12:41:45 +00:00
|
|
|
/* If we are initializing for the correct class, we can actually perform
|
|
|
|
* initializations:
|
|
|
|
*/
|
|
|
|
internal->kind = kind;
|
2012-01-04 09:20:32 +00:00
|
|
|
internal->options = theOptions;
|
2012-01-06 12:22:30 +00:00
|
|
|
internal->stringValue = @"";
|
2009-02-09 16:16:11 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2012-01-06 12:22:30 +00:00
|
|
|
- (BOOL) isEqual: (id)other
|
|
|
|
{
|
|
|
|
NSString *s;
|
|
|
|
NSArray *c;
|
|
|
|
|
|
|
|
if (other == (id)self)
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NO == [other isKindOfClass: [self class]])
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ([(NSXMLNode*)other kind] != internal->kind)
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
s = [other name];
|
|
|
|
if (s != internal->name && NO == [s isEqual: internal->name])
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
s = [other URI];
|
|
|
|
if (s != internal->URI && NO == [s isEqual: internal->URI])
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
c = [other children];
|
|
|
|
if (c != internal->children && NO == [c isEqual: internal->children])
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
- (NSXMLNodeKind) kind
|
|
|
|
{
|
2012-01-04 12:41:45 +00:00
|
|
|
return internal->kind;
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSUInteger) level
|
|
|
|
{
|
|
|
|
NSUInteger level = 0;
|
2012-01-04 12:41:45 +00:00
|
|
|
NSXMLNode *tmp = internal->parent;
|
2009-02-09 16:16:11 +00:00
|
|
|
|
|
|
|
while (tmp != nil)
|
|
|
|
{
|
|
|
|
level++;
|
2012-01-04 12:41:45 +00:00
|
|
|
tmp = GSIVar(tmp, parent);
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
return level;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString*) localName
|
|
|
|
{
|
|
|
|
return [self notImplemented: _cmd]; // FIXME ... fetch from libxml
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString*) name
|
|
|
|
{
|
2012-01-12 18:50:56 +00:00
|
|
|
xmlNodePtr node = (xmlNodePtr)(internal->node);
|
|
|
|
if (node->name)
|
|
|
|
return StringFromXMLString(node->name,strlen((char *)node->name));
|
|
|
|
else
|
|
|
|
return @"";
|
|
|
|
//return internal->name;
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
2011-10-01 18:43:29 +00:00
|
|
|
- (NSXMLNode*) _nodeFollowingInNaturalDirection: (BOOL)forward
|
|
|
|
{
|
2012-01-04 12:41:45 +00:00
|
|
|
NSXMLNode *ancestor = internal->parent;
|
2011-10-01 18:43:29 +00:00
|
|
|
NSXMLNode *candidate = nil;
|
|
|
|
|
|
|
|
/* Node walking is a depth-first thingy. Hence, we consider children first: */
|
2012-01-04 09:20:32 +00:00
|
|
|
if (0 != internal->childCount)
|
2011-10-01 18:43:29 +00:00
|
|
|
{
|
2012-01-01 07:38:53 +00:00
|
|
|
NSUInteger theIndex = 0;
|
|
|
|
if (NO == forward)
|
|
|
|
{
|
2012-01-04 09:20:32 +00:00
|
|
|
theIndex = (internal->childCount) - 1;
|
2012-01-01 07:38:53 +00:00
|
|
|
}
|
2012-01-04 09:20:32 +00:00
|
|
|
candidate = [internal->children objectAtIndex: theIndex];
|
2011-10-01 18:43:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* If there are no children, we move on to siblings: */
|
|
|
|
if (nil == candidate)
|
|
|
|
{
|
2012-01-01 07:38:53 +00:00
|
|
|
if (forward)
|
|
|
|
{
|
2012-01-04 09:20:32 +00:00
|
|
|
candidate = internal->nextSibling;
|
2012-01-01 07:38:53 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-01-04 09:20:32 +00:00
|
|
|
candidate = internal->previousSibling;
|
2012-01-01 07:38:53 +00:00
|
|
|
}
|
2011-10-01 18:43:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* If there are no siblings left for the receiver, we recurse down to the root
|
|
|
|
* of the tree until we find an ancestor with further siblings: */
|
|
|
|
while ((nil == candidate) && (nil != ancestor))
|
|
|
|
{
|
2012-01-01 07:38:53 +00:00
|
|
|
if (forward)
|
|
|
|
{
|
|
|
|
candidate = [ancestor nextSibling];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
candidate = [ancestor previousSibling];
|
|
|
|
}
|
2012-01-04 12:41:45 +00:00
|
|
|
ancestor = GSIVar(ancestor, parent);
|
2011-10-01 18:43:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* No children, no next siblings, no next siblings for any ancestor: We are
|
|
|
|
* the last node */
|
|
|
|
if (nil == candidate)
|
2012-01-01 07:38:53 +00:00
|
|
|
{
|
|
|
|
return nil;
|
|
|
|
}
|
2011-10-01 18:43:29 +00:00
|
|
|
|
|
|
|
/* Sanity check: Namespace and attribute nodes are skipped: */
|
2012-01-04 12:41:45 +00:00
|
|
|
if ((NSXMLAttributeKind == GSIVar(candidate, kind))
|
|
|
|
|| (NSXMLNamespaceKind == GSIVar(candidate, kind)))
|
2012-01-01 07:38:53 +00:00
|
|
|
{
|
|
|
|
return [candidate _nodeFollowingInNaturalDirection: forward];
|
|
|
|
}
|
2011-10-01 18:43:29 +00:00
|
|
|
return candidate;
|
|
|
|
}
|
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
- (NSXMLNode*) nextNode
|
|
|
|
{
|
2011-10-01 18:43:29 +00:00
|
|
|
return [self _nodeFollowingInNaturalDirection: YES];
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSXMLNode*) nextSibling
|
|
|
|
{
|
2012-01-04 09:20:32 +00:00
|
|
|
return internal->nextSibling;
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (id) objectValue
|
|
|
|
{
|
2012-01-04 12:41:45 +00:00
|
|
|
return internal->objectValue;
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSXMLNode*) parent
|
|
|
|
{
|
2012-01-04 12:41:45 +00:00
|
|
|
return internal->parent;
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString*) prefix
|
|
|
|
{
|
|
|
|
return [self notImplemented: _cmd]; // FIXME ... fetch from libxml
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSXMLNode*) previousNode
|
|
|
|
{
|
2011-10-01 18:43:29 +00:00
|
|
|
return [self _nodeFollowingInNaturalDirection: NO];
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSXMLNode*) previousSibling
|
|
|
|
{
|
2012-01-04 09:20:32 +00:00
|
|
|
return internal->previousSibling;
|
2011-10-01 18:43:29 +00:00
|
|
|
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSXMLDocument*) rootDocument
|
|
|
|
{
|
2012-01-11 17:54:44 +00:00
|
|
|
xmlNodePtr node = (xmlNodePtr)(internal->node);
|
|
|
|
NSXMLDocument *ancestor = (NSXMLDocument *)(node->doc->_private);
|
2011-10-01 18:43:29 +00:00
|
|
|
return (NSXMLDocument*)ancestor;
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString*) stringValue
|
|
|
|
{
|
2012-01-11 17:54:44 +00:00
|
|
|
xmlNodePtr node = (xmlNodePtr)(internal->node);
|
2012-01-12 18:50:56 +00:00
|
|
|
if (node->content)
|
|
|
|
return StringFromXMLString(node->content,strlen((char *)node->content));
|
|
|
|
else
|
|
|
|
return @"";
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString*) URI
|
|
|
|
{
|
2012-01-04 12:41:45 +00:00
|
|
|
return internal->URI; // FIXME ... fetch from libxml
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString*) XMLString
|
|
|
|
{
|
|
|
|
return [self XMLStringWithOptions: 0];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString*) XMLStringWithOptions: (NSUInteger)options
|
|
|
|
{
|
2012-01-11 17:54:44 +00:00
|
|
|
NSString *string = nil;
|
|
|
|
xmlNodePtr node = (xmlNodePtr)[self _node];
|
|
|
|
xmlChar *buf = NULL;
|
|
|
|
xmlDocPtr doc = node->doc;
|
|
|
|
xmlBufferPtr buffer = NULL;
|
|
|
|
int error = 0;
|
|
|
|
int len = 0;
|
2012-01-03 17:15:29 +00:00
|
|
|
|
2012-01-11 17:54:44 +00:00
|
|
|
error = xmlNodeDump(buffer, doc, node, 1, 1);
|
|
|
|
buf = buffer->content;
|
|
|
|
len = buffer->size;
|
|
|
|
string = StringFromXMLString(buf,len);
|
|
|
|
AUTORELEASE(string);
|
2012-01-03 17:15:29 +00:00
|
|
|
|
2012-01-11 17:54:44 +00:00
|
|
|
return string;
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setObjectValue: (id)value
|
|
|
|
{
|
2012-01-04 12:41:45 +00:00
|
|
|
ASSIGN(internal->objectValue, value);
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
2012-01-02 07:27:56 +00:00
|
|
|
- (void) setName: (NSString *)name
|
2009-02-09 16:16:11 +00:00
|
|
|
{
|
2012-01-06 12:22:30 +00:00
|
|
|
if (NSXMLInvalidKind != internal->kind)
|
|
|
|
{
|
2012-01-12 18:50:56 +00:00
|
|
|
xmlNodePtr node = (xmlNodePtr)(internal->node);
|
|
|
|
node->name = XMLStringCopy(name);
|
|
|
|
//ASSIGNCOPY(internal->name, name);
|
2012-01-06 12:22:30 +00:00
|
|
|
}
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setStringValue: (NSString*)string
|
|
|
|
{
|
|
|
|
[self setStringValue: string resolvingEntities: NO];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setURI: (NSString*)URI
|
|
|
|
{
|
2012-01-06 12:22:30 +00:00
|
|
|
if (NSXMLInvalidKind != internal->kind)
|
|
|
|
{
|
|
|
|
ASSIGNCOPY(internal->URI, URI);
|
|
|
|
}
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setStringValue: (NSString*)string resolvingEntities: (BOOL)resolve
|
|
|
|
{
|
2012-01-11 17:54:44 +00:00
|
|
|
xmlNodePtr node = (xmlNodePtr)(internal->node);
|
2012-01-04 12:41:45 +00:00
|
|
|
if (resolve == NO)
|
2012-01-03 17:15:29 +00:00
|
|
|
{
|
2012-01-11 17:54:44 +00:00
|
|
|
node->content = (xmlChar *)[string UTF8String];
|
2012-01-03 17:15:29 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-01-04 12:41:45 +00:00
|
|
|
// need to actually resolve entities...
|
2012-01-11 17:54:44 +00:00
|
|
|
node->content = (xmlChar *)[string UTF8String];
|
2012-01-06 12:22:30 +00:00
|
|
|
}
|
|
|
|
if (nil == internal->stringValue)
|
|
|
|
{
|
2012-01-11 17:54:44 +00:00
|
|
|
node->content = (xmlChar *)[@"" UTF8String]; // string value may not be nil
|
2012-01-03 17:15:29 +00:00
|
|
|
}
|
2009-02-09 16:16:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString*) XPath
|
|
|
|
{
|
|
|
|
return [self notImplemented: _cmd];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray*) nodesForXPath: (NSString*)xpath error: (NSError**)error
|
|
|
|
{
|
|
|
|
return [self notImplemented: _cmd];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray*) objectsForXQuery: (NSString*)xquery
|
|
|
|
constants: (NSDictionary*)constants
|
|
|
|
error: (NSError**)error
|
|
|
|
{
|
|
|
|
return [self notImplemented: _cmd];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray*) objectsForXQuery: (NSString*)xquery error: (NSError**)error
|
|
|
|
{
|
|
|
|
return [self notImplemented: _cmd];
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
|