0
|
1 |
"{ Package: 'stx:goodies/xmlsuite/xmlreaderimpl' }"
|
|
2 |
|
|
3 |
"{ NameSpace: XMLv2 }"
|
|
4 |
|
|
5 |
XMLReader subclass:#VWXMLReader
|
|
6 |
instanceVariableNames:'parser'
|
|
7 |
classVariableNames:''
|
|
8 |
poolDictionaries:''
|
|
9 |
category:'XML Suite-SAX2-XMLReaders'
|
|
10 |
!
|
|
11 |
|
|
12 |
XML::StreamWrapper subclass:#StreamWrapper
|
|
13 |
instanceVariableNames:'line col'
|
|
14 |
classVariableNames:''
|
|
15 |
poolDictionaries:''
|
|
16 |
privateIn:VWXMLReader
|
|
17 |
!
|
|
18 |
|
|
19 |
XML::XMLParserStX subclass:#XMLParser
|
|
20 |
instanceVariableNames:'xmlReader'
|
|
21 |
classVariableNames:''
|
|
22 |
poolDictionaries:''
|
|
23 |
privateIn:VWXMLReader
|
|
24 |
!
|
|
25 |
|
|
26 |
|
|
27 |
!VWXMLReader methodsFor:'SAX2 interface - Locator'!
|
|
28 |
|
|
29 |
getColumnNumber
|
|
30 |
"Superclass says that I am responsible to implement this method"
|
|
31 |
|
|
32 |
^parser getColumnNumber
|
|
33 |
|
|
34 |
"Created: / 19-05-2005 / 10:45:03 / masca"
|
|
35 |
"Modified: / 11-07-2005 / 12:07:19 / masca"
|
|
36 |
"Modified: / 04-08-2005 / 11:21:01 / janfrog"
|
|
37 |
!
|
|
38 |
|
|
39 |
getLineNumber
|
|
40 |
"Superclass says that I am responsible to implement this method"
|
|
41 |
|
|
42 |
^parser getLineNumber
|
|
43 |
|
|
44 |
"Created: / 19-05-2005 / 10:45:03 / masca"
|
|
45 |
"Modified: / 11-07-2005 / 12:07:10 / masca"
|
|
46 |
"Modified: / 04-08-2005 / 11:21:15 / janfrog"
|
|
47 |
! !
|
|
48 |
|
|
49 |
!VWXMLReader methodsFor:'SAX2 interface - extensions'!
|
|
50 |
|
|
51 |
parseFragmentStream:aStream
|
|
52 |
"Superclass says that I am responsible to implement this method"
|
|
53 |
|
|
54 |
^self parseStream:aStream
|
|
55 |
|
|
56 |
"Created: / 03-05-2005 / 11:46:46 / janfrog"
|
|
57 |
!
|
|
58 |
|
|
59 |
parseStream:aStream
|
|
60 |
|
|
61 |
| saxBuilder |
|
|
62 |
|
|
63 |
aStream isExternalStream ifTrue:[
|
|
64 |
aStream text
|
|
65 |
] ifFalse:[
|
|
66 |
aStream isBinary ifTrue:[aStream on:aStream collection asString]
|
|
67 |
].
|
|
68 |
|
|
69 |
|
|
70 |
saxBuilder := VWSAXBuilder
|
|
71 |
driver: self getContentHandler
|
|
72 |
source: aStream.
|
|
73 |
parser := XMLv2::VWXMLReader::XMLParser on: aStream.
|
|
74 |
parser xmlReader:self.
|
|
75 |
parser builder:saxBuilder.
|
|
76 |
parser validate:false.
|
|
77 |
parser scanDocument.
|
|
78 |
|
|
79 |
"Created: / 03-05-2005 / 11:46:46 / janfrog"
|
|
80 |
"Modified: / 18-05-2005 / 11:04:37 / masca"
|
|
81 |
"Modified: / 06-06-2006 / 09:23:21 / janfrog"
|
|
82 |
! !
|
|
83 |
|
|
84 |
!VWXMLReader::StreamWrapper methodsFor:'accessing'!
|
|
85 |
|
|
86 |
col
|
|
87 |
^ col
|
|
88 |
|
|
89 |
"Created: / 04-08-2005 / 11:19:20 / janfrog"
|
|
90 |
!
|
|
91 |
|
|
92 |
line
|
|
93 |
^ line
|
|
94 |
|
|
95 |
"Created: / 04-08-2005 / 11:19:20 / janfrog"
|
|
96 |
! !
|
|
97 |
|
|
98 |
!VWXMLReader::StreamWrapper methodsFor:'declaration'!
|
|
99 |
|
|
100 |
encodingDeclIn: aParser
|
|
101 |
|
|
102 |
| enc |
|
|
103 |
^stream peek = $e
|
|
104 |
ifTrue:
|
|
105 |
[| encoding |
|
|
106 |
self mustFind: 'encoding' errorOn: aParser.
|
|
107 |
self skipSpaceIn: aParser.
|
|
108 |
self mustFind: '=' errorOn: aParser.
|
|
109 |
self skipSpaceIn: aParser.
|
|
110 |
encoding := self quotedString.
|
|
111 |
aParser validateEncoding: encoding.
|
|
112 |
((stream respondsTo: #encoder)
|
|
113 |
and: [stream encoder nameOfEncoding asLowercase ~= (XMLv2::VWXMLReader::XMLParser mapEncoding: encoding) asLowercase])
|
|
114 |
ifTrue:
|
|
115 |
[enc := (CharacterEncoder encoderFor:
|
|
116 |
(XMLv2::VWXMLReader::XMLParser mapEncoding: encoding) asSymbol).
|
|
117 |
|
|
118 |
stream encoder: enc].
|
|
119 |
true]
|
|
120 |
ifFalse: [false]
|
|
121 |
|
|
122 |
"Created: / 15-06-2005 / 15:00:01 / janfrog"
|
|
123 |
"Modified: / 22-06-2005 / 17:02:27 / masca"
|
|
124 |
! !
|
|
125 |
|
|
126 |
!VWXMLReader::StreamWrapper methodsFor:'initialization'!
|
|
127 |
|
|
128 |
stream: str protocol: key name: value entity: ent
|
|
129 |
|
|
130 |
super stream: str protocol: key name: value entity: ent.
|
|
131 |
|
|
132 |
line := 1.
|
|
133 |
col := 0.
|
|
134 |
stream := EncodedStream
|
|
135 |
stream:stream
|
|
136 |
encoder:(CharacterEncoder encoderForUTF8)
|
|
137 |
|
|
138 |
"Created: / 15-06-2005 / 14:58:51 / janfrog"
|
|
139 |
"Modified: / 04-08-2005 / 11:42:05 / janfrog"
|
|
140 |
! !
|
|
141 |
|
|
142 |
!VWXMLReader::StreamWrapper methodsFor:'streaming'!
|
|
143 |
|
|
144 |
nextFor:aParser
|
|
145 |
|ch ascii|
|
|
146 |
|
|
147 |
ch := stream next.
|
|
148 |
(ch = Character lf) ifTrue:[
|
|
149 |
line := line + 1.
|
|
150 |
col := 0.
|
|
151 |
] ifFalse:[
|
|
152 |
|
|
153 |
col := col + 1.
|
|
154 |
].
|
|
155 |
ch isNil ifTrue:[
|
|
156 |
^ nil
|
|
157 |
].
|
|
158 |
ascii := ch codePoint.
|
|
159 |
|
|
160 |
"to speed up things, do a quick check for
|
|
161 |
common characters"
|
|
162 |
|
|
163 |
ascii >= 16r20 ifTrue:[
|
|
164 |
ascii <= 16rFF ifTrue:[
|
|
165 |
^ ch
|
|
166 |
].
|
|
167 |
] ifFalse:[
|
|
168 |
isInternal ifFalse:[
|
|
169 |
ch == cr ifTrue:[
|
|
170 |
stream peekFor:lf.
|
|
171 |
^ aParser eol
|
|
172 |
] ifFalse:[
|
|
173 |
ch == lf ifTrue:[
|
|
174 |
^ aParser eol
|
|
175 |
]
|
|
176 |
]
|
|
177 |
].
|
|
178 |
].
|
|
179 |
(aParser isIllegalCharacter:ascii) ifTrue:[
|
|
180 |
aParser
|
|
181 |
notPermitted:'a character with Unicode value ' , ascii printString
|
|
182 |
].
|
|
183 |
^ ch
|
|
184 |
|
|
185 |
"Created: / 04-08-2005 / 11:16:48 / janfrog"
|
|
186 |
!
|
|
187 |
|
|
188 |
skip: n
|
|
189 |
|
|
190 |
| str idx lfs |
|
|
191 |
n < 0 ifTrue:[^stream skip:n].
|
|
192 |
str := stream next:n.
|
|
193 |
lfs := str occurrencesOf:Character lf.
|
|
194 |
lfs isZero
|
|
195 |
ifTrue:[
|
|
196 |
col := col + str size
|
|
197 |
] ifFalse:[
|
|
198 |
idx := str lastIndexOf:Character lf.
|
|
199 |
line := line + lfs .
|
|
200 |
col := col + (str size - idx).
|
|
201 |
].
|
|
202 |
|
|
203 |
"Created: / 04-08-2005 / 11:18:37 / janfrog"
|
|
204 |
"Modified: / 04-08-2005 / 14:54:25 / janfrog"
|
|
205 |
! !
|
|
206 |
|
|
207 |
!VWXMLReader::XMLParser class methodsFor:'utilities'!
|
|
208 |
|
|
209 |
mapEncoding: anEncoding
|
|
210 |
|
|
211 |
| enc |
|
|
212 |
enc := anEncoding asLowercase.
|
|
213 |
"enc = 'utf-8' ifTrue: [^'UTF_8'].
|
|
214 |
enc = 'utf-16' ifTrue: [^'UTF_16'].
|
|
215 |
enc = 'iso-8859-1' ifTrue: [^'ISO8859_1']."
|
|
216 |
^enc
|
|
217 |
|
|
218 |
"Created: / 22-06-2005 / 17:11:03 / masca"
|
|
219 |
!
|
|
220 |
|
|
221 |
readFileContents: fn
|
|
222 |
|
|
223 |
| s p |
|
|
224 |
s := VWXMLReader::StreamWrapper
|
|
225 |
stream: (fn withEncoding: #UTF_8) readStream
|
|
226 |
protocol: 'file'
|
|
227 |
name: nil
|
|
228 |
entity: nil.
|
|
229 |
p := self new.
|
|
230 |
p lineEndLF.
|
|
231 |
^[s checkEncoding.
|
|
232 |
s contentsFor: p]
|
|
233 |
ensure: [s close]
|
|
234 |
|
|
235 |
"Created: / 15-06-2005 / 15:04:40 / janfrog"
|
|
236 |
! !
|
|
237 |
|
|
238 |
!VWXMLReader::XMLParser methodsFor:'SAX2 interface - Locator'!
|
|
239 |
|
|
240 |
getColumnNumber
|
|
241 |
"Superclass says that I am responsible to implement this method"
|
|
242 |
|
|
243 |
^currentSource col
|
|
244 |
|
|
245 |
"Modified: / 11-07-2005 / 12:07:19 / masca"
|
|
246 |
"Created: / 04-08-2005 / 11:20:26 / janfrog"
|
|
247 |
!
|
|
248 |
|
|
249 |
getLineNumber
|
|
250 |
"Superclass says that I am responsible to implement this method"
|
|
251 |
|
|
252 |
^currentSource line
|
|
253 |
|
|
254 |
"Modified: / 11-07-2005 / 12:07:10 / masca"
|
|
255 |
"Created: / 04-08-2005 / 11:20:26 / janfrog"
|
|
256 |
! !
|
|
257 |
|
|
258 |
!VWXMLReader::XMLParser methodsFor:'accessing'!
|
|
259 |
|
|
260 |
dtdFile:aString
|
|
261 |
|
|
262 |
"Created: / 18-05-2005 / 11:04:10 / masca"
|
|
263 |
!
|
|
264 |
|
|
265 |
xmlReader
|
|
266 |
^ xmlReader
|
|
267 |
|
|
268 |
"Created: / 25-10-2005 / 13:09:54 / janfrog"
|
|
269 |
!
|
|
270 |
|
|
271 |
xmlReader:something
|
|
272 |
xmlReader := something.
|
|
273 |
|
|
274 |
"Created: / 25-10-2005 / 13:09:54 / janfrog"
|
|
275 |
! !
|
|
276 |
|
|
277 |
!VWXMLReader::XMLParser methodsFor:'element processing'!
|
|
278 |
|
|
279 |
elementContent: tag openedIn: str
|
|
280 |
|
|
281 |
| data elements str1 result p |
|
|
282 |
data := (UnicodeString new: 32) writeStream.
|
|
283 |
elements := OrderedCollection new.
|
|
284 |
[hereChar == nil
|
|
285 |
ifTrue: [self expected: ('end tag for %<<1s>>' expandMacrosWith: tag)].
|
|
286 |
hereChar = $<
|
|
287 |
ifTrue:
|
|
288 |
[data position0Based = 0
|
|
289 |
ifFalse:
|
|
290 |
[data := data contents.
|
|
291 |
" (data findString: ']]>' startingAt: 1) = 0
|
|
292 |
ifFalse: [self halt: 'including ]]> in element content'].
|
|
293 |
" self with: elements add: (builder makeText: data).
|
|
294 |
data := (UnicodeString new: 32) writeStream].
|
|
295 |
str1 := currentSource.
|
|
296 |
(self skipIf: '</')
|
|
297 |
ifTrue:
|
|
298 |
[result := self closeTag: tag return: elements asArray.
|
|
299 |
str == lastSource
|
|
300 |
ifFalse: [self expected: 'elements properly nested within entities'].
|
|
301 |
self isValidating
|
|
302 |
ifTrue:
|
|
303 |
[p := self dtd elementFor: tag.
|
|
304 |
p == nil
|
|
305 |
ifTrue: [self invalid: ('Using a tag (<1s>) without declaring it is not valid' expandMacrosWith: tag)]
|
|
306 |
ifFalse: [p validateTag: tag content: result for: self]].
|
|
307 |
^result]
|
|
308 |
ifFalse: [(self skipIf: '<?')
|
|
309 |
ifTrue: [self with: elements add: (self completePI: str1)]
|
|
310 |
ifFalse: [(self skipIf: '<!![CDATA[')
|
|
311 |
ifTrue: [self with: elements add: (self completeCDATA: str1)]
|
|
312 |
ifFalse: [(self skipIf: '<!!--')
|
|
313 |
ifTrue: [self with: elements add: (self completeComment: str1)]
|
|
314 |
ifFalse: [self with: elements add: self element]]]]]
|
|
315 |
ifFalse: [hereChar = $&
|
|
316 |
ifTrue:
|
|
317 |
[str1 := currentSource.
|
|
318 |
(self skipIf: '&#')
|
|
319 |
ifTrue: [self charEntity: data startedIn: str1]
|
|
320 |
ifFalse: [self getNextChar; generalEntityInText: data canBeExternal: true]]
|
|
321 |
ifFalse:
|
|
322 |
[data nextPut: hereChar.
|
|
323 |
self getNextChar]]. true] whileTrue "repeat"
|
|
324 |
|
|
325 |
"Created: / 22-06-2005 / 09:23:51 / masca"
|
|
326 |
"Modified: / 15-05-2006 / 14:50:28 / janfrog"
|
|
327 |
!
|
|
328 |
|
|
329 |
generalEntityInText: str canBeExternal: external
|
|
330 |
|
|
331 |
| exp nm str1 |
|
|
332 |
str1 := lastSource.
|
|
333 |
nm := self getSimpleName.
|
|
334 |
hereChar = $;
|
|
335 |
ifFalse: [self expected: 'semicolon'].
|
|
336 |
currentSource = str1
|
|
337 |
ifFalse: [self expected: 'proper nesting of entity references within other entity references'].
|
|
338 |
|
|
339 |
^self.
|
|
340 |
|
|
341 |
exp := self dtd generalEntityAt: nm.
|
|
342 |
exp == nil
|
|
343 |
ifTrue: [
|
|
344 |
"/self warn: ('The general entity "<1s>" has not been defined'
|
|
345 |
"/ expandMacrosWith: nm)
|
|
346 |
].
|
|
347 |
exp == nil
|
|
348 |
ifTrue:
|
|
349 |
[self shouldTestWFCEntityDeclared
|
|
350 |
ifTrue: [self malformed: 'General entity used but not defined'].
|
|
351 |
str nextPut: $&; nextPutAll: nm; nextPut: $;.
|
|
352 |
self getNextChar]
|
|
353 |
ifFalse:
|
|
354 |
[(external or: [exp isExternal not])
|
|
355 |
ifFalse: [self notPermitted: 'external entities in attribute values'].
|
|
356 |
exp isParsed
|
|
357 |
ifFalse: [self malformed: 'References to unparsed entities other than in an attribute of type ENTITY are not permitted'].
|
|
358 |
"exp streamFor: self"].
|
|
359 |
|
|
360 |
"Created: / 07-11-2006 / 21:09:05 / janfrog"
|
|
361 |
! !
|
|
362 |
|
|
363 |
!VWXMLReader::XMLParser methodsFor:'initialization'!
|
|
364 |
|
|
365 |
wrapStream:aStream protocol:protocolString name:name
|
|
366 |
|
|
367 |
|protocol|
|
|
368 |
|
|
369 |
protocolString notNil ifTrue:[
|
|
370 |
protocol := protocolString.
|
|
371 |
] ifFalse:[
|
|
372 |
protocol := aStream isExternalStream ifTrue:['file'] ifFalse:['internal']
|
|
373 |
].
|
|
374 |
|
|
375 |
^VWXMLReader::StreamWrapper
|
|
376 |
stream: aStream
|
|
377 |
protocol: protocol
|
|
378 |
name: name
|
|
379 |
entity: nil
|
|
380 |
|
|
381 |
"Created: / 15-06-2005 / 15:05:38 / janfrog"
|
|
382 |
! !
|
|
383 |
|
|
384 |
!VWXMLReader::XMLParser methodsFor:'private'!
|
|
385 |
|
|
386 |
malformed: aString
|
|
387 |
|
|
388 |
self xmlReader getErrorHandler fatalError: aString
|
|
389 |
|
|
390 |
"Created: / 25-10-2005 / 13:09:07 / janfrog"
|
|
391 |
!
|
|
392 |
|
|
393 |
warn: aString
|
|
394 |
|
|
395 |
self malformed: 'XML parser warning: ' , aString
|
|
396 |
|
|
397 |
"Created: / 22-06-2005 / 10:12:49 / masca"
|
|
398 |
! !
|
|
399 |
|
|
400 |
!VWXMLReader class methodsFor:'documentation'!
|
|
401 |
|
|
402 |
version
|
|
403 |
^ '$Header: /opt/data/cvs/stx/goodies/xmlsuite/xmlreaderimpl/XMLv2__VWXMLReader.st,v 1.4 2006-11-08 09:29:50 vranyj1 Exp $'
|
|
404 |
! !
|