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 "DOMSaxHandler.h"
23 #include "DOMImplementation.h"
24 #include "DOMDocument.h"
25 #include "DOMElement.h"
27 #include <SaxObjC/SaxObjC.h>
29 @interface NSObject(LineInfoProtocol)
30 - (void)setLine:(int)_line;
33 @implementation DOMSaxHandler
35 static BOOL printErrors = NO;
37 - (id)initWithDOMImplementation:(id)_domImpl {
38 if ((self = [super init])) {
39 self->dom = [_domImpl retain];
40 self->maxErrorCount = 100; // this also includes NPSOBJ in HTML !
48 idom = [[NGDOMImplementation alloc] init];
50 return [self initWithDOMImplementation:idom];
54 [self->document release];
56 [self->locator release];
57 [self->fatals release];
58 [self->errors release];
59 [self->warnings release];
63 - (void)setDocumentLocator:(id<NSObject,SaxLocator>)_loc {
64 ASSIGN(self->locator, _loc);
68 return self->document;
72 ASSIGN(self->document, (id)nil);
73 [self->fatals removeAllObjects];
74 [self->errors removeAllObjects];
75 [self->warnings removeAllObjects];
80 return self->errorCount;
82 - (int)fatalErrorCount {
83 return [self->fatals count];
86 return [self->warnings count];
88 - (int)maxErrorCount {
89 return self->maxErrorCount;
92 - (NSArray *)warnings {
93 return [[self->warnings copy] autorelease];
96 return [[self->errors copy] autorelease];
98 - (NSArray *)fatalErrors {
99 return [[self->fatals copy] autorelease];
104 - (id)_nodeForSaxAttrWithName:(NSString *)_name
105 namespace:(NSString *)_uri
106 rawName:(NSString *)_rawName
107 type:(NSString *)_saxType value:(NSString *)_saxValue
112 attr = [self->document createAttribute:_name namespaceURI:_uri];
120 r = [_rawName rangeOfString:@":"];
122 nsPrefix = [_rawName substringToIndex:r.location];
126 [attr setPrefix:nsPrefix];
128 /* add content to attribute */
130 if ([_saxType isEqualToString:@"CDATA"] || (_saxType == nil)) {
133 NSAssert(self->document, @"missing document object");
135 if ((content = [self->document createTextNode:_saxValue]))
136 [attr appendChild:content];
138 NSLog(@"couldn't create text node !");
141 NSLog(@"unsupported sax attr type '%@' !", _saxType);
148 - (void)startDocument {
151 [self->document release]; self->document = nil;
152 self->errorCount = 0;
155 docType = [self->dom createDocumentType:nil
156 publicId:[self->locator publicId]
157 systemId:[self->locator systemId]];
159 self->document = [self->dom createDocumentWithName:nil
161 documentType:docType];
162 self->document = [self->document retain];
164 //NSLog(@"started doc: %@", self->document);
166 self->currentElement = self->document;
168 - (void)endDocument {
169 self->currentElement = nil;
172 - (void)startPrefixMapping:(NSString *)_prefix uri:(NSString *)_uri {
173 //printf("ns-map: %s=%s\n", [_prefix cString], [_uri cString]);
175 - (void)endPrefixMapping:(NSString *)_prefix {
176 //printf("ns-unmap: %s\n", [_prefix cString]);
179 - (void)startElement:(NSString *)_localName
180 namespace:(NSString *)_ns
181 rawName:(NSString *)_rawName
182 attributes:(id<SaxAttributes>)_attrs
188 elem = [self->document createElement:_localName namespaceURI:_ns];
190 NSLog(@"%s: couldn't create element for tag '%@'", __PRETTY_FUNCTION__,
194 if ([elem respondsToSelector:@selector(setLine:)])
195 [elem setLine:[self->locator lineNumber]];
200 r = [_rawName rangeOfString:@":"];
201 nsPrefix = (r.length > 0)
202 ? [_rawName substringToIndex:r.location]
209 [elem setPrefix:nsPrefix];
211 NSAssert(self->currentElement, @"no current element !");
213 [self->currentElement appendChild:elem];
214 self->currentElement = elem;
216 /* process attributes */
220 for (i = 0, count = [_attrs count]; i < count; i++) {
223 // NSLog(@"attr %@", [_attrs nameAtIndex:i]);
225 attr = [self _nodeForSaxAttrWithName:[_attrs nameAtIndex:i]
226 namespace:[_attrs uriAtIndex:i]
227 rawName:[_attrs rawNameAtIndex:i]
228 type:[_attrs typeAtIndex:i]
229 value:[_attrs valueAtIndex:i]];
231 NSLog(@"couldn't create attribute for SAX attr %@, element %@",
236 /* add node to element */
238 if ([elem setAttributeNodeNS:attr] == nil)
239 NSLog(@"couldn't add attribute %@ to element %@", attr, elem);
243 - (void)endElement:(NSString *)_localName
244 namespace:(NSString *)_ns
245 rawName:(NSString *)_rawName
249 parent = [self->currentElement parentNode];
251 NSAssert1(parent, @"no parent for current element %@ !",
252 self->currentElement);
254 self->currentElement = parent;
258 - (void)characters:(unichar *)_chars length:(int)_len {
262 data = [[NSString alloc] initWithCharacters:_chars length:_len];
263 charNode = [self->document createTextNode:data];
264 [data release]; data = nil;
266 [self->currentElement appendChild:charNode];
268 - (void)ignorableWhitespace:(unichar *)_chars length:(int)_len {
271 - (void)processingInstruction:(NSString *)_pi data:(NSString *)_data {
274 piNode = [self->document createProcessingInstruction:_pi data:_data];
276 [self->currentElement appendChild:piNode];
280 - (xmlEntityPtr)getEntity:(NSString *)_name {
281 NSLog(@"get entity %@", _name);
284 - (xmlEntityPtr)getParameterEntity:(NSString *)_name {
285 NSLog(@"get para entity %@", _name);
290 /* lexical handler */
292 - (void)comment:(unichar *)_chars length:(int)_len {
299 data = [[NSString alloc] initWithCharacters:_chars length:_len];
300 commentNode = [self->document createComment:data];
301 [data release]; data = nil;
303 [self->currentElement appendChild:commentNode];
306 - (void)startDTD:(NSString *)_name
307 publicId:(NSString *)_pub
308 systemId:(NSString *)_sys
325 - (id)resolveEntityWithPublicId:(NSString *)_pubId
326 systemId:(NSString *)_sysId
328 NSLog(@"shall resolve entity with '%@' '%@'", _pubId, _sysId);
334 - (void)warning:(SaxParseException *)_exception {
338 sysId = [[_exception userInfo] objectForKey:@"systemId"];
339 line = [[[_exception userInfo] objectForKey:@"line"] intValue];
341 NSLog(@"DOM XML WARNING(%@:%i): %@", sysId, line, [_exception reason]);
343 if (self->warnings == nil)
344 self->warnings = [[NSMutableArray alloc] initWithCapacity:32];
347 [self->warnings addObject:_exception];
350 - (void)error:(SaxParseException *)_exception {
357 sysId = [[_exception userInfo] objectForKey:@"systemId"];
358 line = [[[_exception userInfo] objectForKey:@"line"] intValue];
360 NSLog(@"DOM XML ERROR(%@:%i[%@]): %@ (errcount=%i,max=%i)", sysId, line,
361 [[_exception userInfo] objectForKey:@"parser"],
363 self->errorCount, self->maxErrorCount);
366 if (self->errors == nil)
367 self->errors = [[NSMutableArray alloc] initWithCapacity:32];
370 [self->errors addObject:_exception];
373 - (void)fatalError:(SaxParseException *)_exception {
377 sysId = [[_exception userInfo] objectForKey:@"systemId"];
378 line = [[[_exception userInfo] objectForKey:@"line"] intValue];
380 NSLog(@"DOM XML FATAL(%@:%i[%@]): %@", sysId, line,
381 [[_exception userInfo] objectForKey:@"parser"],
382 [_exception reason]);
384 if (self->fatals == nil)
385 self->fatals = [[NSMutableArray alloc] initWithCapacity:32];
388 [self->fatals addObject:_exception];
395 - (void)notationDeclaration:(NSString *)_name
396 publicId:(NSString *)_pubId
397 systemId:(NSString *)_sysId
399 NSLog(@"decl: notation %@ pub=%@ sys=%@", _name, _pubId, _sysId);
402 - (void)unparsedEntityDeclaration:(NSString *)_name
403 publicId:(NSString *)_pubId
404 systemId:(NSString *)_sysId
405 notationName:(NSString *)_notName
407 NSLog(@"decl: unparsed entity %@ pub=%@ sys=%@ not=%@",
408 _name, _pubId, _sysId, _notName);
413 - (void)attributeDeclaration:(NSString *)_attributeName
414 elementName:(NSString *)_elementName
415 type:(NSString *)_type
416 defaultType:(NSString *)_defType
417 defaultValue:(NSString *)_defValue
419 NSLog(@"decl: attr %@[%@] type '%@' default '%@'[%@]",
420 _attributeName, _elementName, _type, _defValue, _defType);
423 - (void)elementDeclaration:(NSString *)_name contentModel:(NSString *)_model {
424 NSLog(@"decl: element %@ model %@", _name, _model);
427 - (void)externalEntityDeclaration:(NSString *)_name
428 publicId:(NSString *)_pub
429 systemId:(NSString *)_sys
431 NSLog(@"decl: e-entity %@ pub %@ sys %@", _name, _pub, _sys);
434 - (void)internalEntityDeclaration:(NSString *)_name value:(NSString *)_value {
435 NSLog(@"decl: i-entity %@ value %@", _name, _value);
438 @end /* DOMSaxHandler */
441 @implementation DOMSaxHandler(SubHandler)
443 - (unsigned)tagDepth {
444 return self->tagDepth;
448 return [self document];
451 - (void)setNamespaces:(NSString *)_namespaces {
452 // not yet implemented
455 @end /* DOMSaxHandler(SubHandler) */