2 Copyright (C) 2000-2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
6 OGo 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 OGo 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 OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 A small demonstration program to show how to write a SAX handler
25 using SaxObjC. It goes over a RSS channel file and collects the
26 item information in a dictionary.
28 As you will see it's quite a bit of work dealing with SAX ;-)
31 #import <Foundation/Foundation.h>
32 #include <SaxObjC/SaxObjC.h>
34 /* ******************** the SAX handler ****************** */
36 @interface RSSSaxHandler : SaxDefaultHandler
38 NSMutableArray *entries;
39 NSMutableDictionary *entry;
42 BOOL isInItem; /* are we inside an 'item' tag ? */
43 NSString *value; /* the (PCDATA) content of a tag */
46 - (NSArray *)rssEntries;
50 @implementation RSSSaxHandler
53 if ((self = [super init])) {
54 self->entries = [[NSMutableArray alloc] initWithCapacity:16];
55 self->entry = [[NSMutableDictionary alloc] initWithCapacity:8];
60 [self->entry release];
61 [self->entries release];
65 /* accessing results */
67 - (NSArray *)rssEntries {
68 return [[self->entries copy] autorelease];
73 - (void)startDocument {
74 /* ensure consistent state */
75 [self->entries removeAllObjects];
81 - (void)startElement:(NSString *)_localName
82 namespace:(NSString *)_ns
83 rawName:(NSString *)_rawName
84 attributes:(id<SaxAttributes>)_attributes
86 if ([_localName isEqualToString:@"item"]) {
87 [self->entry removeAllObjects];
91 /* always reset content when entering a new tag */
92 [self->value release]; self->value = nil;
95 - (void)endElement:(NSString *)_localName
96 namespace:(NSString *)_ns
97 rawName:(NSString *)_rawName
99 if ([_localName isEqualToString:@"item"]) {
100 /* found end of item */
102 [self->entries addObject:[[self->entry copy] autorelease]];
104 else if (self->isInItem) {
105 /* any tag inside of an item is a key for the entry dict */
107 /* if we collected a PCDATA value, add it */
108 [self->entry setObject:self->value forKey:_localName];
109 [self->value release]; self->value = nil;
114 - (void)characters:(unichar *)_chars length:(int)_len {
118 /* only track content if we are inside an item ... */
122 Note: The characters callback is allowed to be called multiple times
123 by the parser (makes writing parsers easier, but complicates the
126 s = [[NSString alloc] initWithCharacters:_chars length:_len];
128 self->value = [[self->value stringByAppendingString:s] copy];
135 @end /* RSSSaxHandler */
137 /* ******************** C main section ******************** */
139 int main(int argc, char **argv, char **env) {
140 NSAutoreleasePool *pool;
141 #if LIB_FOUNDATION_LIBRARY
142 [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
145 pool = [[NSAutoreleasePool alloc] init];
147 if ([[[NSProcessInfo processInfo] arguments] count] < 2) {
148 fprintf(stderr, "usage: %s <rssfile>\n",
149 [[[[NSProcessInfo processInfo] arguments] lastObject] cString]);
153 /* the interesting section */
157 id<SaxXMLReader> parser;
160 /* step a, get a parser for XML */
161 parser = [[SaxXMLReaderFactory standardXMLReaderFactory]
162 createXMLReaderForMimeType:@"text/xml"];
164 /* step b, create a SAX handler and attach it to the parser */
165 sax = [[[RSSSaxHandler alloc] init] autorelease];
166 [parser setContentHandler:sax];
167 [parser setErrorHandler:sax];
169 /* step c, parse :-) */
171 args = [[[NSProcessInfo processInfo] arguments] objectEnumerator];
172 [args nextObject]; /* skip tool name */
174 while ((arg = [args nextObject])) {
177 /* the parser takes URLs, NSData's, NSString's */
178 arg = [[[NSURL alloc] initFileURLWithPath:arg] autorelease];
180 /* let the parser parse (it will report SAX events to the handler) */
181 [parser parseFromSource:arg];
183 /* now query the handler for the result */
184 entries = [sax rssEntries];
186 /* TODO: use NSPropertyListSerialization on OSX */
187 printf("%s\n", [[entries description] cString]);