]> err.no Git - sope/blob - sope-xml/DOM/DOMNode.m
synced with latest additions and bumped framework versions
[sope] / sope-xml / DOM / DOMNode.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
6   SOPE is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with SOPE; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21
22 #include <DOM/DOMNode.h>
23 #include <DOM/DOMDocument.h>
24 #include <DOM/DOMProcessingInstruction.h>
25 #include <DOM/DOMCharacterData.h>
26 #include <DOM/DOMElement.h>
27 #include <DOM/DOMAttribute.h>
28 #include "common.h"
29
30 NSString *DOMNodeName(id<DOMNode> _node) {
31   switch ([_node nodeType]) {
32     case DOM_ATTRIBUTE_NODE:
33       return [(id<DOMAttr>)_node name];
34     case DOM_CDATA_SECTION_NODE:
35       return @"#cdata-section";
36     case DOM_COMMENT_NODE:
37       return @"#comment";
38     case DOM_DOCUMENT_NODE:
39       return @"#document";
40     case DOM_DOCUMENT_FRAGMENT_NODE:
41       return @"#document-fragment";
42     case DOM_ELEMENT_NODE:
43       return [(id<DOMElement>)_node tagName];
44     case DOM_PROCESSING_INSTRUCTION_NODE:
45       return [(id<DOMProcessingInstruction>)_node target];
46     case DOM_TEXT_NODE:
47       return @"#text";
48       
49     case DOM_DOCUMENT_TYPE_NODE:
50     case DOM_ENTITY_NODE:
51     case DOM_ENTITY_REFERENCE_NODE:
52     case DOM_NOTATION_NODE:
53     default:
54       NSLog(@"ERROR: unknown node type %i !", [_node nodeType]);
55       return nil;
56   }
57 }
58
59 NSString *DOMNodeValue(id _node) {
60   switch ([_node nodeType]) {
61     case DOM_ATTRIBUTE_NODE:
62       return [_node value];
63       
64     case DOM_CDATA_SECTION_NODE:
65     case DOM_COMMENT_NODE:
66     case DOM_TEXT_NODE:
67       return [(id<DOMCharacterData>)_node data];
68
69     case DOM_DOCUMENT_NODE:
70     case DOM_DOCUMENT_FRAGMENT_NODE:
71     case DOM_ELEMENT_NODE:
72       return nil;
73       
74     case DOM_PROCESSING_INSTRUCTION_NODE:
75       return [(id<DOMProcessingInstruction>)_node data];
76       
77     case DOM_DOCUMENT_TYPE_NODE:
78     case DOM_ENTITY_NODE:
79     case DOM_ENTITY_REFERENCE_NODE:
80     case DOM_NOTATION_NODE:
81     default:
82       NSLog(@"ERROR: unknown node type %i !", [_node nodeType]);
83       return nil;
84   }
85 }
86
87 @implementation NGDOMNode
88
89 - (void)_domNodeRegisterParentNode:(id)_parent {
90 }
91 - (void)_domNodeForgetParentNode:(id)_parent {
92 }
93
94 /* owner */
95
96 - (IDOMDocument)ownerDocument {
97   id node;
98
99   for (node = [self parentNode]; node; node = [node parentNode]) {
100     if ([node nodeType] == DOM_DOCUMENT_NODE)
101       return node;
102     if ([node nodeType] == DOM_DOCUMENT_FRAGMENT_NODE)
103       return node;
104   }
105   
106   return nil;
107 }
108
109 /* attributes */
110
111 - (DOMNodeType)nodeType {
112   return DOM_UNKNOWN_NODE;
113 }
114
115 - (NSString *)nodeName {
116   return DOMNodeName(self);
117 }
118 - (NSString *)nodeValue {
119   return DOMNodeValue(self);
120 }
121
122 - (id)subclassResponsibility:(SEL)_sel {
123   [self doesNotRecognizeSelector:_sel];
124   return nil;
125 }
126
127 - (NSString *)localName {
128   /* introduced in DOM level 2 */
129   return [self subclassResponsibility:_cmd];
130 }
131 - (NSString *)namespaceURI {
132   /* introduced in DOM level 2 */
133   return [self subclassResponsibility:_cmd];
134 }
135
136 - (void)setPrefix:(NSString *)_prefix {
137   /* introduced in DOM level 2 */
138   [self subclassResponsibility:_cmd];
139 }
140 - (NSString *)prefix {
141   /* introduced in DOM level 2 */
142   return [self subclassResponsibility:_cmd];
143 }
144
145 /* element attributes */
146
147 - (id<NSObject,DOMNamedNodeMap>)attributes {
148   /* returns a NamedNodeList */
149   return [self subclassResponsibility:_cmd];
150 }
151
152 /* modification */
153
154 - (BOOL)_isValidChildNode:(id)_node {
155   return NO;
156 }
157
158 - (id<NSObject,DOMNode>)removeChild:(id<NSObject,DOMNode>)_node {
159   return nil;
160 }
161 - (id<NSObject,DOMNode>)appendChild:(id<NSObject,DOMNode>)_node {
162   return nil;
163 }
164
165 /* navigation */
166
167 - (id<NSObject,DOMNode>)parentNode {
168   return [self subclassResponsibility:_cmd];
169 }
170
171 - (id<NSObject,DOMNode>)previousSibling {
172   NGDOMNode *parent;
173   
174   if ((parent = (NGDOMNode *)[self parentNode]) == nil) return nil;
175   if (parent == nil) return nil;
176   if (![parent respondsToSelector:@selector(_domNodeBeforeNode:)]) return nil;
177   return [parent _domNodeBeforeNode:self];
178 }
179 - (id<NSObject,DOMNode>)nextSibling {
180   NGDOMNode *parent;
181   
182   if ((parent = (NGDOMNode *)[self parentNode]) == nil) return nil;
183   if (parent == nil) return nil;
184   if (![parent respondsToSelector:@selector(_domNodeBeforeNode:)]) return nil;
185   return [parent _domNodeAfterNode:self];
186 }
187
188 - (id<NSObject,DOMNodeList>)childNodes {
189   return nil;
190 }
191 - (BOOL)hasChildNodes {
192   return NO;
193 }
194 - (id<NSObject,DOMNode>)firstChild {
195   return nil;
196 }
197 - (id<NSObject,DOMNode>)lastChild {
198   return nil;
199 }
200
201 /* key/value coding */
202
203 - (id)valueForUndefinedKey:(NSString *)_key {
204   /* default is to raise an exception, we just return nil */
205   return nil;
206 }
207
208 /* description */
209
210 - (NSString *)description {
211   return [NSString stringWithFormat:
212                      @"<0x%08X[%@]: name=%@ parent=%@ type=%i #children=%i>",
213                      self, NSStringFromClass([self class]),
214                      [self nodeName],
215                      [[self parentNode] nodeName],
216                      [self nodeType],
217                      [self hasChildNodes] ? [[self childNodes] length] : 0];
218 }
219
220 @end /* NGDOMNode */
221
222 #include "DOMXMLOutputter.h"
223 #include "DOMCharacterData.h"
224
225 @implementation NGDOMNode(Additions)
226
227 - (NSString *)nodeTypeString {
228   switch ([self nodeType]) {
229     case DOM_ATTRIBUTE_NODE:              return @"attribute";
230     case DOM_CDATA_SECTION_NODE:          return @"cdata-section";
231     case DOM_COMMENT_NODE:                return @"comment";
232     case DOM_DOCUMENT_NODE:               return @"document";
233     case DOM_DOCUMENT_FRAGMENT_NODE:      return @"document-fragment";
234     case DOM_ELEMENT_NODE:                return @"element";
235     case DOM_PROCESSING_INSTRUCTION_NODE: return @"processing-instruction";
236     case DOM_TEXT_NODE:                   return @"text";
237     case DOM_DOCUMENT_TYPE_NODE:          return @"document-type";
238     case DOM_ENTITY_NODE:                 return @"entity";
239     case DOM_ENTITY_REFERENCE_NODE:       return @"entity-reference";
240     case DOM_NOTATION_NODE:               return @"notation";
241     default:
242       return @"unknown";
243   }
244 }
245
246 - (NSString *)xmlStringValue {
247   DOMXMLOutputter *out;
248   NSMutableString *s;
249   NSString *r;
250
251   s   = [[NSMutableString alloc] initWithCapacity:1024];
252   out = [[DOMXMLOutputter alloc] init];
253
254   [out outputNode:self to:s];
255   [out release];
256   
257   r = [s copy];
258   [s release];
259   return [r autorelease];
260 }
261
262 - (NSData *)xmlDataValue {
263   return [[self xmlStringValue] dataUsingEncoding:NSUTF8StringEncoding];
264 }
265
266 - (NSString *)textValue {
267   NSMutableString *s;
268   
269   s = [NSMutableString stringWithCapacity:256];
270
271   switch ([self nodeType]) {
272     case DOM_ELEMENT_NODE:
273     case DOM_DOCUMENT_NODE:
274     case DOM_ATTRIBUTE_NODE:
275       if ([self hasChildNodes]) {
276         id children;
277         unsigned i, count;
278         
279         children = [self childNodes];
280         for (i = 0, count = [children count]; i < count; i++) {
281           NSString *cs;
282
283           cs = [[children objectAtIndex:i] textValue];
284           if (cs) [s appendString:cs];
285         }
286       }
287       break;
288       
289     case DOM_TEXT_NODE:
290     case DOM_COMMENT_NODE:
291     case DOM_CDATA_SECTION_NODE:
292       [s appendString:[(id<DOMCharacterData>)self data]];
293       break;
294       
295     default:
296       return nil;
297   }
298   
299   return [[s copy] autorelease];
300 }
301
302 @end /* NGDOMNode(Additions) */
303
304 @implementation NSArray(DOMNodeList)
305
306 - (unsigned)length {
307   return [self count];
308 }
309
310 @end /* NSObject(DOMNodeList) */