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 DOMDocument
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:(DOMImplementation *)_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];
113 return self->doctype;
115 - (DOMImplementation *)implementation {
119 - (id)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;
159 - (DOMDocument *)ownerDocument {
164 /* document cannot be nested */
168 /* document cannot be nested */
171 - (id)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)getElementsByTagName:(NSString *)_tagName {
200 /* introduced in DOM2, should return a *live* list ! */
201 NSMutableArray *array;
202 DOMNodePreorderWalker *walker;
206 if (![self hasChildNodes])
212 array = [NSMutableArray array];
214 if ([_tagName isEqualToString:@"*"]) {
217 sel = @selector(_walk_getElementsByTagNameAddAll:);
220 ctx = [NSArray arrayWithObjects:_tagName, array, nil];
221 sel = @selector(_walk_getElementsByTagName:);
224 walker = [[DOMNodePreorderWalker alloc]
229 [walker walkNode:self];
231 [walker release]; walker = nil;
233 return [[array copy] autorelease];
235 - (id)getElementsByTagName:(NSString *)_tagName namespaceURI:(NSString *)_uri {
236 [self doesNotRecognizeSelector:_cmd];
240 - (id)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)createElement:(NSString *)_tagName {
288 elem = [[[self domElementClass]
290 initWithTagName:_tagName];
291 return [elem autorelease];
293 - (id)createElement:(NSString *)_tagName namespaceURI:(NSString *)_uri {
295 elem = [[[self domElementNSClass]
297 initWithTagName:_tagName namespaceURI:_uri];
298 return [elem autorelease];
301 - (id)createDocumentFragment {
303 elem = [[[self domDocumentFragmentClass] alloc] init];
304 return [elem autorelease];
307 - (id)createTextNode:(NSString *)_data {
309 elem = [[[self domTextNodeClass] alloc] initWithString:_data];
310 return [elem autorelease];
312 - (id)createComment:(NSString *)_data {
314 elem = [[[self domCommentClass] alloc] initWithString:_data];
315 return [elem autorelease];
317 - (id)createCDATASection:(NSString *)_data {
319 elem = [[[self domCDATAClass] alloc] initWithString:_data];
320 return [elem autorelease];
323 - (id)createProcessingInstruction:(NSString *)_target data:(NSString *)_data {
325 elem = [[[self domProcessingInstructionClass]
327 initWithTarget:_target data:_data];
328 return [elem autorelease];
331 - (id)createAttribute:(NSString *)_name {
333 elem = [[[self domAttributeClass]
336 return [elem autorelease];
338 - (id)createAttribute:(NSString *)_name namespaceURI:(NSString *)_uri {
340 elem = [[[self domAttributeNSClass]
342 initWithName:_name namespaceURI:_uri];
343 return [elem autorelease];
346 - (id)createEntityReference:(NSString *)_name {
348 elem = [[[self domEntityReferenceClass] alloc] initWithName:_name];
349 return [elem autorelease];
352 @end /* DOMDocument */
354 @implementation DOMDocument(QPValues)
356 - (NSException *)setQueryPathValue:(id)_value {
357 return [NSException exceptionWithName:@"QueryPathEvalException"
358 reason:@"cannot set query-path value on DOMDocument !"
361 - (id)queryPathValue {
362 return [self documentElement];
365 @end /* DOMDocument(QPValues) */