2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
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
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.
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
22 #include <DOM/DOMDocument.h>
23 #include <DOM/DOMImplementation.h>
24 #include <DOM/DOMElement.h>
25 #include <DOM/DOMNodeWalker.h>
26 #include <DOM/DOMProcessingInstruction.h>
27 #include <DOM/DOMElement.h>
28 #include <DOM/DOMAttribute.h>
29 #include <DOM/DOMEntityReference.h>
30 #include "DOMSaxBuilder.h"
33 //#define PROF_DEALLOC 1
35 @implementation NGDOMDocument
37 + (id)documentFromData:(NSData *)_data {
40 builder = [[[DOMSaxBuilder alloc] init] autorelease];
41 return [builder buildFromData:_data];
43 + (id)documentFromString:(NSString *)_string {
44 return [self documentFromData:
45 [_string dataUsingEncoding:NSISOLatin1StringEncoding]];
47 + (id)documentFromURI:(NSString *)_uri {
50 builder = [[[DOMSaxBuilder alloc] init] autorelease];
51 return [builder buildFromContentsOfFile:_uri];
54 - (id)initWithName:(NSString *)_qname
55 namespaceURI:(NSString *)_uri
56 documentType:(id)_doctype
57 dom:(NGDOMImplementation *)_dom
59 self->dom = [_dom retain];
60 self->qname = [_qname copy];
61 self->uri = [_uri copy];
62 self->doctype = [_doctype retain];
68 NSDate *start = [NSDate date];
71 [self->errors release];
72 [self->warnings release];
74 [self->qname release];
76 [self->doctype release];
80 printf("%s: %.3fs\n", __PRETTY_FUNCTION__,
81 [NSDate timeIntervalSinceDate:start]);
87 - (void)addErrors:(NSArray *)_errors {
88 if (self->errors == nil)
89 self->errors = [_errors copy];
94 self->errors = [[tmp arrayByAddingObjectsFromArray:_errors] copy];
98 - (void)addWarnings:(NSArray *)_errors {
99 if (self->warnings == nil)
100 self->warnings = [_errors copy];
104 tmp = self->warnings;
105 self->warnings = [[tmp arrayByAddingObjectsFromArray:_errors] copy];
112 - (id<NSObject,DOMDocumentType>)doctype {
113 return self->doctype;
115 - (NGDOMImplementation *)implementation {
119 - (id<NSObject,DOMElement>)documentElement {
123 if ((children = [self childNodes]) == nil)
126 for (i = 0, count = [children count]; i < count; i++) {
129 node = [children objectAtIndex:i];
130 if ([node nodeType] == DOM_ELEMENT_NODE)
138 - (BOOL)_isValidChildNode:(id)_node {
139 switch ([_node nodeType]) {
140 case DOM_ELEMENT_NODE:
141 case DOM_PROCESSING_INSTRUCTION_NODE:
142 case DOM_COMMENT_NODE:
143 case DOM_DOCUMENT_TYPE_NODE:
151 - (DOMNodeType)nodeType {
152 return DOM_DOCUMENT_NODE;
155 - (id<NSObject,DOMNamedNodeMap>)attributes {
159 - (IDOMDocument)ownerDocument {
163 - (id<NSObject,DOMNode>)parentNode {
164 /* document cannot be nested */
167 - (id<NSObject,DOMNode>)nextSibling {
168 /* document cannot be nested */
171 - (id<NSObject,DOMNode>)previousSibling {
172 /* document cannot be nested */
176 - (void)_walk_getElementsByTagName:(id)_walker {
179 node = [_walker currentNode];
180 if ([node nodeType] != DOM_ELEMENT_NODE)
183 if (![[node tagName] isEqualToString:
184 [(NSArray *)[_walker context] objectAtIndex:0]])
185 /* tagname doesn't match */
188 [[(NSArray *)[_walker context] objectAtIndex:1] addObject:node];
190 - (void)_walk_getElementsByTagNameAddAll:(id)_walker {
193 node = [_walker currentNode];
194 if ([node nodeType] != DOM_ELEMENT_NODE)
197 [(NSMutableArray *)[_walker context] addObject:node];
199 - (id<NSObject,DOMNodeList>)getElementsByTagName:(NSString *)_tagName {
200 /* introduced in DOM2, should return a *live* list ! */
201 NSMutableArray *array;
202 NGDOMNodePreorderWalker *walker;
206 if (![self hasChildNodes])
212 array = [NSMutableArray arrayWithCapacity:4];
214 if ([_tagName isEqualToString:@"*"]) {
217 sel = @selector(_walk_getElementsByTagNameAddAll:);
220 ctx = [NSArray arrayWithObjects:_tagName, array, nil];
221 sel = @selector(_walk_getElementsByTagName:);
224 walker = [[NGDOMNodePreorderWalker alloc]
225 initWithTarget:self selector:sel context:ctx];
227 [walker walkNode:self];
229 [walker release]; walker = nil;
231 return [[array copy] autorelease];
233 - (id<NSObject,DOMNodeList>)getElementsByTagName:(NSString *)_tagName
234 namespaceURI:(NSString *)_uri
236 [self doesNotRecognizeSelector:_cmd];
240 - (id<NSObject,DOMElement>)getElementById:(NSString *)_eid {
244 Note: The DOM implementation must have information that says which
245 attributes are of type ID. Attributes with the name "ID" are not of
246 type ID unless so defined.
247 Implementations that do not know whether attributes are of type ID
248 or not are expected to return null.
255 - (Class)domElementClass {
256 return [self->dom domElementClass];
258 - (Class)domElementNSClass {
259 return [self->dom domElementNSClass];
261 - (Class)domDocumentFragmentClass {
262 return [self->dom domDocumentFragmentClass];
264 - (Class)domTextNodeClass {
265 return [self->dom domTextNodeClass];
267 - (Class)domCommentClass {
268 return [self->dom domCommentClass];
270 - (Class)domCDATAClass {
271 return [self->dom domCDATAClass];
273 - (Class)domProcessingInstructionClass {
274 return [self->dom domProcessingInstructionClass];
276 - (Class)domAttributeClass {
277 return [self->dom domAttributeClass];
279 - (Class)domAttributeNSClass {
280 return [self->dom domAttributeNSClass];
282 - (Class)domEntityReferenceClass {
283 return [self->dom domEntityReferenceClass];
286 - (id<NSObject,DOMElement>)createElement:(NSString *)_tagName {
288 elem = [[[self domElementClass]
290 initWithTagName:_tagName];
291 return [elem autorelease];
293 - (id<NSObject,DOMElement>)createElement:(NSString *)_tagName
294 namespaceURI:(NSString *)_uri
297 elem = [[[self domElementNSClass]
299 initWithTagName:_tagName namespaceURI:_uri];
300 return [elem autorelease];
303 - (id<NSObject,DOMDocumentFragment>)createDocumentFragment {
305 elem = [[[self domDocumentFragmentClass] alloc] init];
306 return [elem autorelease];
309 - (id<NSObject,DOMText>)createTextNode:(NSString *)_data {
311 elem = [[[self domTextNodeClass] alloc] initWithString:_data];
312 return [elem autorelease];
314 - (id<NSObject,DOMComment>)createComment:(NSString *)_data {
316 elem = [[[self domCommentClass] alloc] initWithString:_data];
317 return [elem autorelease];
319 - (id<NSObject,DOMCDATASection>)createCDATASection:(NSString *)_data {
321 elem = [[[self domCDATAClass] alloc] initWithString:_data];
322 return [elem autorelease];
325 - (id<NSObject,DOMProcessingInstruction>)createProcessingInstruction:
326 (NSString *)_target data:(NSString *)_data
329 elem = [[[self domProcessingInstructionClass]
331 initWithTarget:_target data:_data];
332 return [elem autorelease];
335 - (id<NSObject,DOMAttr>)createAttribute:(NSString *)_name {
337 elem = [[[self domAttributeClass]
340 return [elem autorelease];
342 - (id<NSObject,DOMAttr>)createAttribute:(NSString *)_name
343 namespaceURI:(NSString *)_uri
346 elem = [[[self domAttributeNSClass]
348 initWithName:_name namespaceURI:_uri];
349 return [elem autorelease];
352 - (id<NSObject,DOMEntityReference>)createEntityReference:(NSString *)_name {
354 elem = [[[self domEntityReferenceClass] alloc] initWithName:_name];
355 return [elem autorelease];
360 - (NSException *)setQueryPathValue:(id)_value {
361 return [NSException exceptionWithName:@"QueryPathEvalException"
362 reason:@"cannot set query-path value on DOMDocument !"
365 - (id)queryPathValue {
366 return [self documentElement];
369 @end /* NGDOMDocument */