]> err.no Git - sope/blob - sope-xml/samples/saxxml.m
added support for XML-RPC 'nil' type
[sope] / sope-xml / samples / saxxml.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 <SaxObjC/SaxObjC.h>
23 #import <Foundation/Foundation.h>
24
25 /*
26   Usage:
27
28     saxxml -XMLReader libxmlHTMLSAXDriver test.html
29 */
30
31 @interface MySAXHandler : SaxDefaultHandler
32 {
33   id  locator;
34   int indent;
35 }
36
37 - (void)indent;
38
39 @end
40
41 @interface SaxXMLReaderFactory(Pathes)
42 - (NSArray *)saxReaderSearchPathes;
43 @end
44
45 static void usage(const char *n) {
46   fprintf(stderr, 
47           "Usage: %s <file1> <file2> ...\n"
48           "\n"
49           "Arguments (Defaults):\n"
50           "  -XMLReader <classname> - select the SAX driver class\n"
51           "  --dirs                 - just print the dirs containing drivers\n"
52           "\n"
53           "Samples:\n"
54           "  %s /etc/X11/xkb/rules/xfree86.xml\n"
55           "  %s -XMLReader STXSaxDriver structured-document.stx\n"
56           "  %s -XMLReader VSiCalSaxDriver event.ics\n"
57           "  %s -XMLReader VSvCardSaxDriver steve.vcf\n"
58           , n, n, n, n, n);
59 }
60
61 static void listSaxScanDirs(void) {
62   NSArray *a;
63   unsigned i, count;
64   
65   a = [[SaxXMLReaderFactory standardXMLReaderFactory] saxReaderSearchPathes];
66   for (i = 0, count = [a count]; i < count; i++)
67     printf("%s\n", [[a objectAtIndex:i] cString]);
68   
69   if (i == 0) {
70     fprintf(stderr, "found no search pathes!\n");
71     exit(1);
72   }
73 }
74
75 int main(int argc, char **argv, char **env) {
76   id<NSObject,SaxXMLReader> parser;
77   id           sax;
78   NSEnumerator *paths;
79   NSString     *path;
80   NSAutoreleasePool *pool;
81   NSString          *cwd;
82   BOOL hadPath = NO;
83   
84   pool   = [[NSAutoreleasePool alloc] init];
85 #if LIB_FOUNDATION_LIBRARY
86   [NSProcessInfo initializeWithArguments:argv count:argc environment:env];
87 #endif
88   
89   parser = [[SaxXMLReaderFactory standardXMLReaderFactory] createXMLReader];
90   cwd    = [[NSFileManager defaultManager] currentDirectoryPath];
91   
92   if (parser == nil) {
93     fprintf(stderr, "could not load a SAX driver bundle!\n");
94     exit(2);
95   }
96   
97   sax = [[MySAXHandler alloc] init];
98   [parser setContentHandler:sax];
99   [parser setDTDHandler:sax];
100   [parser setErrorHandler:sax];
101   
102   [parser setProperty:@"http://xml.org/sax/properties/declaration-handler"
103           to:sax];
104 #if 0
105   [parser setProperty:@"http://xml.org/sax/properties/lexical-handler"
106           to:sax];
107 #endif
108   
109   /* parse */
110
111   paths = [[[NSProcessInfo processInfo] arguments] objectEnumerator];
112   [paths nextObject];
113   while ((path = [paths nextObject]) != nil) {
114     NSAutoreleasePool *pool;
115
116     if ([path isEqualToString:@"--help"]) {
117       usage(argv[0]);
118       exit(0);
119     }
120
121     if ([path isEqualToString:@"--dirs"]) {
122       listSaxScanDirs();
123       exit(0);
124     }
125     
126     if ([path hasPrefix:@"-"]) { /* consume defaults */
127       [paths nextObject];
128       continue;
129     }
130
131     hadPath = YES;
132     
133     pool = [[NSAutoreleasePool alloc] init];
134     
135     if (![path isAbsolutePath])
136       path = [cwd stringByAppendingPathComponent:path];
137     
138     path = [@"file://" stringByAppendingString:path];
139     
140     NS_DURING
141       [parser parseFromSystemId:path];
142     NS_HANDLER
143       abort();
144     NS_ENDHANDLER;
145     
146     [pool release];
147   }
148
149   if (!hadPath) {
150     usage(argv[0]);
151     exit(1);
152   }
153   
154   /* cleanup */
155   
156   [sax release];
157   //[parser release];
158
159   [pool release];
160
161   exit(0);
162   return 0;
163 }
164
165 @implementation MySAXHandler
166
167 - (void)indent {
168   int i;
169   
170   for (i = 0; i < (self->indent * 4); i++)
171     fputc(' ', stdout);
172 }
173
174 @end /* MySAXHandler */
175
176 @implementation MySAXHandler(Documents)
177
178 - (void)dealloc {
179   [self->locator release];
180   [super dealloc];
181 }
182
183 - (void)setDocumentLocator:(id<NSObject,SaxLocator>)_loc {
184   [self->locator autorelease];
185   self->locator = [_loc retain];
186 }
187
188 - (void)startDocument {
189   puts("start document ..");
190   self->indent++;
191 }
192 - (void)endDocument {
193   self->indent--;
194   puts("end document.");
195 }
196
197 - (void)startPrefixMapping:(NSString *)_prefix uri:(NSString *)_uri {
198   [self indent];
199   printf("ns-map: %s=%s\n", [_prefix cString], [_uri cString]);
200 }
201 - (void)endPrefixMapping:(NSString *)_prefix {
202   [self indent];
203   printf("ns-unmap: %s\n", [_prefix cString]);
204 }
205
206 - (void)startElement:(NSString *)_localName
207   namespace:(NSString *)_ns
208   rawName:(NSString *)_rawName
209   attributes:(id<SaxAttributes>)_attrs
210 {
211   int i, c;
212   [self indent];
213   printf("<%s", [_localName cString]);
214   
215   if ([_ns length] > 0)
216     printf(" (ns=%s)", [_ns cString]);
217   
218   for (i = 0, c = [_attrs count]; i < c; i++) {
219     NSString *type;
220     
221     printf(" %s=\"%s\"",
222            [[_attrs nameAtIndex:i] cString],
223            [[_attrs valueAtIndex:i] cString]);
224
225     if (![_ns isEqualToString:[_attrs uriAtIndex:i]])
226       printf("(ns=%s)", [[_attrs uriAtIndex:i] cString]);
227     
228     type = [_attrs typeAtIndex:i];
229     if (![type isEqualToString:@"CDATA"] && (type != nil))
230       printf("[%s]", [type cString]);
231   }
232   puts(">");
233   self->indent++;
234 }
235 - (void)endElement:(NSString *)_localName
236   namespace:(NSString *)_ns
237   rawName:(NSString *)_rawName
238 {
239   self->indent--;
240   [self indent];
241   printf("</%s>\n", [_localName cString]);
242 }
243
244 - (void)characters:(unichar *)_chars length:(int)_len {
245   NSString *str;
246   id tmp;
247   unsigned i, len;
248
249   if (_len == 0) {
250     [self indent];
251     printf("\"\"\n");
252     return;
253   }
254   
255   for (i = 0; i < (unsigned)_len; i++) {
256     if (_chars[i] > 255) {
257       NSLog(@"detected large char: o%04o d%03i h%04X",
258             _chars[i], _chars[i], _chars[i]);
259     }
260   }
261   
262   str = [NSString stringWithCharacters:_chars length:_len];
263   len = [str length];
264   
265   tmp = [str componentsSeparatedByString:@"\n"];
266   str = [tmp componentsJoinedByString:@"\\n"];
267   tmp = [str componentsSeparatedByString:@"\r"];
268   str = [tmp componentsJoinedByString:@"\\r"];
269   
270   [self indent];
271   printf("\"%s\"\n", [str cString]);
272 }
273 - (void)ignorableWhitespace:(unichar *)_chars length:(int)_len {
274   NSString *data;
275   id tmp;
276
277   data = [NSString stringWithCharacters:_chars length:_len];
278   tmp  = [data componentsSeparatedByString:@"\n"];
279   data = [tmp componentsJoinedByString:@"\\n"];
280   tmp  = [data componentsSeparatedByString:@"\r"];
281   data = [tmp componentsJoinedByString:@"\\r"];
282   
283   [self indent];
284   printf("whitespace: \"%s\"\n", [data cString]);
285 }
286
287 - (void)processingInstruction:(NSString *)_pi data:(NSString *)_data {
288   [self indent];
289   printf("PI: '%s' '%s'\n", [_pi cString], [_data cString]);
290 }
291
292 #if 0
293 - (xmlEntityPtr)getEntity:(NSString *)_name {
294   NSLog(@"get entity %@", _name);
295   return NULL;
296 }
297 - (xmlEntityPtr)getParameterEntity:(NSString *)_name {
298   NSLog(@"get para entity %@", _name);
299   return NULL;
300 }
301 #endif
302
303 @end /* MySAXHandler(Documents) */
304
305 @implementation MySAXHandler(EntityResolver)
306
307 - (id)resolveEntityWithPublicId:(NSString *)_pubId
308   systemId:(NSString *)_sysId
309 {
310   [self indent];
311   printf("shall resolve entity with '%s' '%s'",
312          [_pubId cString], [_sysId cString]);
313   return nil;
314 }
315
316 @end /* MySAXHandler(EntityResolver) */
317
318 @implementation MySAXHandler(Errors)
319
320 - (void)warning:(SaxParseException *)_exception {
321   NSLog(@"warning(%@:%i): %@",
322         [[_exception userInfo] objectForKey:@"publicId"],
323         [[[_exception userInfo] objectForKey:@"line"] intValue],
324         [_exception reason]);
325 }
326
327 - (void)error:(SaxParseException *)_exception {
328   NSLog(@"error(%@:%i): %@",
329         [[_exception userInfo] objectForKey:@"publicId"],
330         [[[_exception userInfo] objectForKey:@"line"] intValue],
331         [_exception reason]);
332 }
333
334 - (void)fatalError:(SaxParseException *)_exception {
335   NSLog(@"fatal error(%@:%i): %@",
336         [[_exception userInfo] objectForKey:@"publicId"],
337         [[[_exception userInfo] objectForKey:@"line"] intValue],
338         [_exception reason]);
339   [_exception raise];
340 }
341
342 @end /* MySAXHandler(Errors) */
343
344 @implementation MySAXHandler(DTD)
345
346 - (void)notationDeclaration:(NSString *)_name
347   publicId:(NSString *)_pubId
348   systemId:(NSString *)_sysId
349 {
350   NSLog(@"decl: notation %@ pub=%@ sys=%@", _name, _pubId, _sysId);
351 }
352
353 - (void)unparsedEntityDeclaration:(NSString *)_name
354   publicId:(NSString *)_pubId
355   systemId:(NSString *)_sysId
356   notationName:(NSString *)_notName
357 {
358   NSLog(@"decl: unparsed entity %@ pub=%@ sys=%@ not=%@",
359         _name, _pubId, _sysId, _notName);
360 }
361
362 @end /* MySAXHandler(DTD) */
363
364 @implementation MySAXHandler(Decl)
365
366 - (void)attributeDeclaration:(NSString *)_attributeName
367   elementName:(NSString *)_elementName
368   type:(NSString *)_type
369   defaultType:(NSString *)_defType
370   defaultValue:(NSString *)_defValue
371 {
372   NSLog(@"decl: attr %@[%@] type '%@' default '%@'[%@]",
373         _attributeName, _elementName, _type, _defValue, _defType);
374 }
375
376 - (void)elementDeclaration:(NSString *)_name contentModel:(NSString *)_model {
377   NSLog(@"decl: element %@ model %@", _name, _model);
378 }
379
380 - (void)externalEntityDeclaration:(NSString *)_name
381   publicId:(NSString *)_pub
382   systemId:(NSString *)_sys
383 {
384   NSLog(@"decl: e-entity %@ pub %@ sys %@", _name, _pub, _sys);
385 }
386
387 - (void)internalEntityDeclaration:(NSString *)_name value:(NSString *)_value {
388   NSLog(@"decl: i-entity %@ value %@", _name, _value);
389 }
390
391 @end /* MySAXHandler(Decl) */