|
1 "{ Package: 'stx:goodies/xmlsuite/relaxng' }" |
|
2 |
|
3 "{ NameSpace: RNG }" |
|
4 |
|
5 XMLv2::ContentHandler subclass:#SchemaParser |
|
6 instanceVariableNames:'nodeStack schema currentDefineName refs nsStack' |
|
7 classVariableNames:'BindingNamespace RNGNamespace ActionDictionary' |
|
8 poolDictionaries:'' |
|
9 category:'Relax NG' |
|
10 ! |
|
11 |
|
12 |
|
13 !SchemaParser class methodsFor:'initialization'! |
|
14 |
|
15 initialize |
|
16 |
|
17 ActionDictionary := nil. |
|
18 BindingNamespace := nil. |
|
19 RNGNamespace := nil. |
|
20 |
|
21 " |
|
22 RNG::SchemaParser initialize |
|
23 " |
|
24 |
|
25 "Modified: / 02-05-2005 / 13:14:32 / janfrog" |
|
26 ! ! |
|
27 |
|
28 !SchemaParser class methodsFor:'instance creation'! |
|
29 |
|
30 new |
|
31 ^ self basicNew initialize. |
|
32 |
|
33 "Created: / 03-05-2005 / 11:08:10 / janfrog" |
|
34 ! ! |
|
35 |
|
36 !SchemaParser class methodsFor:'accessing'! |
|
37 |
|
38 actionDictionary |
|
39 |
|
40 ActionDictionary ifNil:[ |
|
41 ActionDictionary := Dictionary new |
|
42 add:'element' -> #startElementDef:; |
|
43 add:'attribute' -> #startAttributeDef:; |
|
44 add:'text' -> #startTextDef:; |
|
45 add:'data' -> #startDataDef:; |
|
46 add:'choice' -> #startChoiceDef:; |
|
47 add:'optional' -> #startOptionalDef:; |
|
48 add:'oneOrMore' -> #startOneOrMoreDef:; |
|
49 add:'zeroOrMore' -> #startZeroOrMoreDef:; |
|
50 add:'group' -> #startGroupDef:; |
|
51 add:'empty' -> #startEmptyDef:; |
|
52 add:'ref' -> #startRefDef:; |
|
53 add:'include' -> #startIncludeDef:; |
|
54 add:'list' -> #startListDef:; |
|
55 yourself |
|
56 ]. |
|
57 ^ActionDictionary |
|
58 |
|
59 " |
|
60 ActionDictionary := nil |
|
61 " |
|
62 |
|
63 "Created: / 30-04-2005 / 18:50:03 / janfrog" |
|
64 "Modified: / 14-05-2005 / 20:12:15 / janfrog" |
|
65 ! |
|
66 |
|
67 bindingNamespace |
|
68 |
|
69 BindingNamespace ifNil:[ |
|
70 BindingNamespace := 'http://www.volny.cz/janfrog/xmlsuite/binding' |
|
71 ]. |
|
72 ^BindingNamespace |
|
73 |
|
74 "Created: / 02-05-2005 / 13:10:02 / janfrog" |
|
75 ! |
|
76 |
|
77 rngNamespace |
|
78 |
|
79 RNGNamespace ifNil:[RNGNamespace := 'http://relaxng.org/ns/structure/1.0']. |
|
80 ^RNGNamespace |
|
81 |
|
82 "Modified: / 02-05-2005 / 13:14:05 / janfrog" |
|
83 ! ! |
|
84 |
|
85 !SchemaParser class methodsFor:'utilities'! |
|
86 |
|
87 schemaFromStream:aStream |
|
88 |
|
89 ^self new schemaFromStream:aStream |
|
90 |
|
91 "Created: / 03-05-2005 / 11:06:11 / janfrog" |
|
92 ! |
|
93 |
|
94 schemaFromURI:aFilename |
|
95 ^ self new schemaFromURI:aFilename |
|
96 |
|
97 "Created: / 03-05-2005 / 11:05:59 / janfrog" |
|
98 "Modified: / 07-06-2005 / 11:51:31 / masca" |
|
99 ! ! |
|
100 |
|
101 !SchemaParser methodsFor:'SAX2 interface'! |
|
102 |
|
103 endDocument |
|
104 |
|
105 "/schema rootPattern initializeAutomaton. |
|
106 "resolving references" |
|
107 schema |
|
108 resolveReferencesFrom:refs; |
|
109 finishLoading. |
|
110 |
|
111 "Created: / 01-05-2005 / 18:48:05 / janfrog" |
|
112 "Modified: / 02-05-2005 / 14:17:24 / janfrog" |
|
113 "Modified: / 07-06-2005 / 11:06:45 / masca" |
|
114 ! |
|
115 |
|
116 endElement:localName namespace:namespace prefix:prefix |
|
117 |
|
118 | topNode | |
|
119 |
|
120 self class rngNamespace = namespace ifFalse:[^self]. |
|
121 localName = 'grammar' ifTrue:[^self]. |
|
122 localName = 'start' ifTrue:[^self]. |
|
123 localName = 'include' ifTrue:[^self]. |
|
124 localName = 'define' ifTrue:[nodeStack pop. ^self]. |
|
125 |
|
126 |
|
127 topNode := nodeStack pop. |
|
128 |
|
129 nodeStack top addChild:topNode. |
|
130 topNode checkContents. |
|
131 topNode postParseFor:self schema. |
|
132 nsStack pop. |
|
133 |
|
134 "Created: / 30-04-2005 / 14:52:30 / janfrog" |
|
135 "Modified: / 14-05-2005 / 21:22:54 / janfrog" |
|
136 "Modified: / 16-05-2005 / 09:23:58 / masca" |
|
137 ! |
|
138 |
|
139 setDocumentLocator:locator |
|
140 |
|
141 schema |
|
142 addSource:locator getSystemId; |
|
143 rootSource:locator getSystemId. |
|
144 |
|
145 "Modified: / 07-06-2005 / 11:31:34 / masca" |
|
146 ! |
|
147 |
|
148 startDocument |
|
149 |
|
150 nodeStack push:schema rootPattern node. |
|
151 refs := Set new. |
|
152 |
|
153 "Created: / 30-04-2005 / 14:07:08 / janfrog" |
|
154 "Modified: / 03-05-2005 / 11:08:30 / janfrog" |
|
155 "Modified: / 07-06-2005 / 11:33:43 / masca" |
|
156 ! |
|
157 |
|
158 startElement:localName namespace:namespace prefix:prefix attributes:attributes |
|
159 |
|
160 | action ns | |
|
161 |
|
162 self class rngNamespace = namespace ifFalse:[^self]. |
|
163 |
|
164 ns := attributes getValueByURI:self class rngNamespace localName:'ns'. |
|
165 ns ifNotNil:[nsStack push:ns] ifNil:[nsStack push:nsStack top]. |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 localName = 'grammar' ifTrue:[^self]. |
|
171 localName = 'start' ifTrue:[^self]. |
|
172 localName = 'define' ifTrue:[ |
|
173 currentDefineName := attributes getValueByURI:self class rngNamespace localName:'name'. |
|
174 nodeStack push:self. |
|
175 ^self |
|
176 ]. |
|
177 action := self class actionDictionary |
|
178 at:localName |
|
179 ifAbsent:[self parsingError:'Unexpected tag: ',localName]. |
|
180 |
|
181 self perform:action with:attributes |
|
182 |
|
183 "Created: / 30-04-2005 / 14:18:35 / janfrog" |
|
184 "Modified: / 03-05-2005 / 10:57:28 / janfrog" |
|
185 "Modified: / 12-05-2005 / 12:26:46 / masca" |
|
186 ! ! |
|
187 |
|
188 !SchemaParser methodsFor:'accessing'! |
|
189 |
|
190 addChild:aNode |
|
191 |
|
192 self schema define:currentDefineName as:aNode. |
|
193 aNode inDefine:true. |
|
194 |
|
195 "Created: / 02-05-2005 / 14:26:33 / janfrog" |
|
196 "Modified: / 03-05-2005 / 10:52:19 / janfrog" |
|
197 "Modified: / 12-05-2005 / 12:12:29 / masca" |
|
198 ! |
|
199 |
|
200 refs |
|
201 |
|
202 ^refs |
|
203 |
|
204 "Created: / 12-05-2005 / 11:50:56 / masca" |
|
205 ! |
|
206 |
|
207 schema |
|
208 ^ schema |
|
209 |
|
210 "Created: / 30-04-2005 / 14:59:39 / janfrog" |
|
211 ! ! |
|
212 |
|
213 !SchemaParser methodsFor:'actions'! |
|
214 |
|
215 startAttributeDef:anAttributes |
|
216 |
|
217 | patternNode name | |
|
218 patternNode := PatternNode for:ComplexTypePattern new. |
|
219 patternNode pattern isForAttribute:true. |
|
220 name := anAttributes getValueByURI:RNGNamespace localName:'name'. |
|
221 name ifNil:[self parsingError:'attribute must have name']. |
|
222 patternNode pattern |
|
223 setNamespace:nsStack top localName:name; |
|
224 initializeBindingInfoFromAttributes:anAttributes. |
|
225 |
|
226 nodeStack push:patternNode |
|
227 |
|
228 "Created: / 30-04-2005 / 14:47:46 / janfrog" |
|
229 "Modified: / 12-05-2005 / 12:27:47 / masca" |
|
230 "Modified: / 14-05-2005 / 18:16:27 / janfrog" |
|
231 ! |
|
232 |
|
233 startChoiceDef:anAttributes |
|
234 |
|
235 nodeStack push:ChoiceNode new |
|
236 |
|
237 "Created: / 30-04-2005 / 19:02:28 / janfrog" |
|
238 ! |
|
239 |
|
240 startDataDef:anAttributes |
|
241 |
|
242 | patternNode type dataTypeLibrary | |
|
243 patternNode := PatternNode for:(PCDataPattern new). |
|
244 patternNode pattern |
|
245 initializeBindingInfoFromAttributes:anAttributes. |
|
246 dataTypeLibrary := self schema defaultDataTypeLibrary. |
|
247 type := anAttributes getValueByURI:RNGNamespace localName:'type'. |
|
248 type ifNil:[self parsingError:'No type specified']. |
|
249 patternNode pattern dataType: |
|
250 (dataTypeLibrary dataTypeWithName:type). |
|
251 |
|
252 |
|
253 nodeStack push:patternNode |
|
254 |
|
255 "Created: / 30-04-2005 / 17:25:59 / janfrog" |
|
256 "Modified: / 14-05-2005 / 22:38:45 / janfrog" |
|
257 ! |
|
258 |
|
259 startElementDef:anAttributes |
|
260 |
|
261 | patternNode name | |
|
262 patternNode := PatternNode for:ComplexTypePattern new. |
|
263 name := anAttributes getValueByURI:RNGNamespace localName:'name'. |
|
264 name ifNil:[self parsingError:'element must have name']. |
|
265 patternNode pattern |
|
266 setNamespace:nsStack top localName:name; |
|
267 initializeBindingInfoFromAttributes:anAttributes. |
|
268 |
|
269 nodeStack push:patternNode |
|
270 |
|
271 "Created: / 30-04-2005 / 14:34:13 / janfrog" |
|
272 "Modified: / 12-05-2005 / 12:27:23 / masca" |
|
273 "Modified: / 14-05-2005 / 18:16:21 / janfrog" |
|
274 ! |
|
275 |
|
276 startEmptyDef:anAttributes |
|
277 |
|
278 nodeStack push:EmptyNode new. |
|
279 "Nothing to do" |
|
280 |
|
281 "Created: / 02-05-2005 / 11:22:40 / janfrog" |
|
282 ! |
|
283 |
|
284 startGroupDef:anAttributes |
|
285 |
|
286 nodeStack push:GroupNode new |
|
287 |
|
288 "Created: / 02-05-2005 / 11:16:35 / janfrog" |
|
289 ! |
|
290 |
|
291 startIncludeDef:attributes |
|
292 |href file| |
|
293 |
|
294 (href := attributes getValueByURI:RNGNamespace localName:'href') |
|
295 ifNil:[ self parsingError:'No "href" attribute in include' ]. |
|
296 file := Schema findFileWithName:href. |
|
297 [ |
|
298 (SchemaIncludeParser for:self) schemaFromURI:file asURI. |
|
299 ] on:CircularSchemaInclusion |
|
300 do:[:ex | Transcript showCR:'[RNG:warning]: ' , ex description ] |
|
301 |
|
302 "Created: / 03-05-2005 / 10:59:09 / janfrog" |
|
303 "Modified: / 07-06-2005 / 12:03:24 / masca" |
|
304 ! |
|
305 |
|
306 startListDef:anAttributes |
|
307 |
|
308 | patternNode | |
|
309 patternNode := PatternNode for:ListPattern new. |
|
310 nodeStack push:patternNode |
|
311 |
|
312 "Modified: / 12-05-2005 / 12:27:23 / masca" |
|
313 "Created: / 14-05-2005 / 20:13:37 / janfrog" |
|
314 ! |
|
315 |
|
316 startOneOrMoreDef:anAttributes |
|
317 |
|
318 nodeStack push:OneOrMoreNode new |
|
319 |
|
320 "Created: / 30-04-2005 / 19:01:55 / janfrog" |
|
321 ! |
|
322 |
|
323 startOptionalDef:anAttributes |
|
324 |
|
325 nodeStack push:OptionalNode new |
|
326 |
|
327 "Created: / 30-04-2005 / 19:02:18 / janfrog" |
|
328 ! |
|
329 |
|
330 startRefDef:attributes |
|
331 |
|
332 | refNode name | |
|
333 refNode := RefNode new. |
|
334 name := attributes getValueByURI:RNGNamespace localName:'name'. |
|
335 name ifNil:[self parsingError:'attribute "type" not found']. |
|
336 refNode |
|
337 name:name; |
|
338 initializeBindingInfoFromAttributes:attributes. |
|
339 self refs add:refNode. |
|
340 |
|
341 nodeStack push:refNode |
|
342 |
|
343 "Created: / 02-05-2005 / 13:48:59 / janfrog" |
|
344 "Modified: / 12-05-2005 / 17:11:24 / masca" |
|
345 ! |
|
346 |
|
347 startTextDef:anAttributes |
|
348 |
|
349 | patternNode | |
|
350 patternNode := PatternNode for:(PCDataPattern new). |
|
351 patternNode pattern |
|
352 initializeBindingInfoFromAttributes:anAttributes. |
|
353 patternNode pattern dataType:TextDataType default. |
|
354 |
|
355 nodeStack push:patternNode |
|
356 |
|
357 "Created: / 30-04-2005 / 17:25:59 / janfrog" |
|
358 "Modified: / 14-05-2005 / 22:38:37 / janfrog" |
|
359 ! |
|
360 |
|
361 startZeroOrMoreDef:anAttributes |
|
362 |
|
363 nodeStack push:ZeroOrMoreNode new |
|
364 |
|
365 "Created: / 30-04-2005 / 19:02:04 / janfrog" |
|
366 ! ! |
|
367 |
|
368 !SchemaParser methodsFor:'error reporting'! |
|
369 |
|
370 parsingError:aString |
|
371 |
|
372 ^SchemaParsingError raiseErrorString:aString |
|
373 |
|
374 "Created: / 30-04-2005 / 14:46:53 / janfrog" |
|
375 ! ! |
|
376 |
|
377 !SchemaParser methodsFor:'initialization'! |
|
378 |
|
379 initialize |
|
380 |
|
381 schema := Schema new. |
|
382 nodeStack := Stack new . |
|
383 (nsStack := Stack new) push:''. |
|
384 |
|
385 "Created: / 03-05-2005 / 11:08:39 / janfrog" |
|
386 "Modified: / 07-06-2005 / 11:33:59 / masca" |
|
387 ! ! |
|
388 |
|
389 !SchemaParser methodsFor:'utilities'! |
|
390 |
|
391 schemaFromStream:aStream |
|
392 |
|
393 |
|
394 XMLv2::XMLReader new |
|
395 setContentHandler:self; |
|
396 parseInputSource:(XMLv2::InputSource onStream:aStream). |
|
397 ^self schema |
|
398 |
|
399 "Created: / 03-05-2005 / 11:05:23 / janfrog" |
|
400 "Modified: / 07-06-2005 / 11:21:22 / masca" |
|
401 ! |
|
402 |
|
403 schemaFromURI:anURI |
|
404 |
|
405 ^anURI isRemote ifTrue:[ |
|
406 self parsingError:'Remote URIs (http://..., ftp://... not yet supported' |
|
407 ] ifFalse:[ |
|
408 self |
|
409 schemaFromStream:(Schema findFileWithName:anURI path) asFilename readStream |
|
410 ] |
|
411 |
|
412 "Created: / 07-06-2005 / 11:51:31 / masca" |
|
413 ! ! |
|
414 |
|
415 !SchemaParser class methodsFor:'documentation'! |
|
416 |
|
417 version |
|
418 ^ '$Header: /opt/data/cvs/stx/goodies/xmlsuite/relaxng/RNG__SchemaParser.st,v 1.1.1.1 2005-11-01 22:07:15 vranyj1 Exp $' |
|
419 ! ! |
|
420 |
|
421 SchemaParser initialize! |