rubysl-rexml 1.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -2
- data/lib/rexml/attlistdecl.rb +56 -56
- data/lib/rexml/attribute.rb +155 -149
- data/lib/rexml/cdata.rb +48 -48
- data/lib/rexml/child.rb +82 -82
- data/lib/rexml/comment.rb +59 -59
- data/lib/rexml/doctype.rb +22 -24
- data/lib/rexml/document.rb +185 -129
- data/lib/rexml/dtd/attlistdecl.rb +7 -7
- data/lib/rexml/dtd/dtd.rb +41 -41
- data/lib/rexml/dtd/elementdecl.rb +13 -13
- data/lib/rexml/dtd/entitydecl.rb +49 -49
- data/lib/rexml/dtd/notationdecl.rb +32 -32
- data/lib/rexml/element.rb +122 -107
- data/lib/rexml/encoding.rb +37 -58
- data/lib/rexml/entity.rb +144 -144
- data/lib/rexml/formatters/default.rb +6 -4
- data/lib/rexml/formatters/pretty.rb +11 -8
- data/lib/rexml/formatters/transitive.rb +4 -3
- data/lib/rexml/functions.rb +33 -21
- data/lib/rexml/instruction.rb +49 -49
- data/lib/rexml/light/node.rb +190 -191
- data/lib/rexml/namespace.rb +39 -39
- data/lib/rexml/node.rb +38 -38
- data/lib/rexml/output.rb +17 -12
- data/lib/rexml/parent.rb +26 -25
- data/lib/rexml/parseexception.rb +4 -4
- data/lib/rexml/parsers/baseparser.rb +90 -61
- data/lib/rexml/parsers/lightparser.rb +41 -43
- data/lib/rexml/parsers/pullparser.rb +1 -1
- data/lib/rexml/parsers/sax2parser.rb +233 -198
- data/lib/rexml/parsers/streamparser.rb +6 -2
- data/lib/rexml/parsers/treeparser.rb +9 -6
- data/lib/rexml/parsers/ultralightparser.rb +40 -40
- data/lib/rexml/parsers/xpathparser.rb +51 -52
- data/lib/rexml/quickpath.rb +247 -248
- data/lib/rexml/rexml.rb +9 -10
- data/lib/rexml/sax2listener.rb +92 -92
- data/lib/rexml/security.rb +27 -0
- data/lib/rexml/source.rb +95 -50
- data/lib/rexml/streamlistener.rb +90 -90
- data/lib/rexml/syncenumerator.rb +3 -4
- data/lib/rexml/text.rb +157 -76
- data/lib/rexml/validation/relaxng.rb +18 -18
- data/lib/rexml/validation/validation.rb +5 -5
- data/lib/rexml/xmldecl.rb +59 -63
- data/lib/rexml/xmltokens.rb +14 -14
- data/lib/rexml/xpath.rb +67 -53
- data/lib/rexml/xpath_parser.rb +49 -38
- data/lib/rubysl/rexml.rb +1 -0
- data/lib/rubysl/rexml/version.rb +1 -1
- data/rubysl-rexml.gemspec +3 -1
- metadata +19 -28
- data/lib/rexml/encodings/CP-1252.rb +0 -103
- data/lib/rexml/encodings/EUC-JP.rb +0 -35
- data/lib/rexml/encodings/ICONV.rb +0 -22
- data/lib/rexml/encodings/ISO-8859-1.rb +0 -7
- data/lib/rexml/encodings/ISO-8859-15.rb +0 -72
- data/lib/rexml/encodings/SHIFT-JIS.rb +0 -37
- data/lib/rexml/encodings/SHIFT_JIS.rb +0 -1
- data/lib/rexml/encodings/UNILE.rb +0 -34
- data/lib/rexml/encodings/US-ASCII.rb +0 -30
- data/lib/rexml/encodings/UTF-16.rb +0 -35
- data/lib/rexml/encodings/UTF-8.rb +0 -18
@@ -3,12 +3,12 @@ require 'rexml/parsers/baseparser'
|
|
3
3
|
require 'rexml/light/node'
|
4
4
|
|
5
5
|
module REXML
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
module Parsers
|
7
|
+
class LightParser
|
8
|
+
def initialize stream
|
9
|
+
@stream = stream
|
10
|
+
@parser = REXML::Parsers::BaseParser.new( stream )
|
11
|
+
end
|
12
12
|
|
13
13
|
def add_listener( listener )
|
14
14
|
@parser.add_listener( listener )
|
@@ -19,42 +19,40 @@ module REXML
|
|
19
19
|
@parser.stream = @stream
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
22
|
+
def parse
|
23
|
+
root = context = [ :document ]
|
24
|
+
while true
|
25
|
+
event = @parser.pull
|
26
|
+
case event[0]
|
27
|
+
when :end_document
|
28
|
+
break
|
29
|
+
when :start_element, :start_doctype
|
30
|
+
new_node = event
|
31
|
+
context << new_node
|
32
|
+
new_node[1,0] = [context]
|
33
|
+
context = new_node
|
34
|
+
when :end_element, :end_doctype
|
35
|
+
context = context[1]
|
36
|
+
else
|
37
|
+
new_node = event
|
38
|
+
context << new_node
|
39
|
+
new_node[1,0] = [context]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
root
|
43
|
+
end
|
44
|
+
end
|
47
45
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
46
|
+
# An element is an array. The array contains:
|
47
|
+
# 0 The parent element
|
48
|
+
# 1 The tag name
|
49
|
+
# 2 A hash of attributes
|
50
|
+
# 3..-1 The child elements
|
51
|
+
# An element is an array of size > 3
|
52
|
+
# Text is a String
|
53
|
+
# PIs are [ :processing_instruction, target, data ]
|
54
|
+
# Comments are [ :comment, data ]
|
55
|
+
# DocTypes are DocType structs
|
56
|
+
# The root is an array with XMLDecls, Text, DocType, Array, Text
|
57
|
+
end
|
60
58
|
end
|
@@ -4,162 +4,171 @@ require 'rexml/namespace'
|
|
4
4
|
require 'rexml/text'
|
5
5
|
|
6
6
|
module REXML
|
7
|
-
|
7
|
+
module Parsers
|
8
8
|
# SAX2Parser
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
class SAX2Parser
|
10
|
+
def initialize source
|
11
|
+
@parser = BaseParser.new(source)
|
12
|
+
@listeners = []
|
13
|
+
@procs = []
|
14
|
+
@namespace_stack = []
|
15
|
+
@has_listeners = false
|
16
|
+
@tag_stack = []
|
17
17
|
@entities = {}
|
18
|
-
|
18
|
+
end
|
19
19
|
|
20
20
|
def source
|
21
21
|
@parser.source
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def add_listener( listener )
|
25
25
|
@parser.add_listener( listener )
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
28
|
+
# Listen arguments:
|
29
|
+
#
|
30
|
+
# Symbol, Array, Block
|
31
|
+
# Listen to Symbol events on Array elements
|
32
|
+
# Symbol, Block
|
33
|
+
# Listen to Symbol events
|
34
|
+
# Array, Listener
|
35
|
+
# Listen to all events on Array elements
|
36
|
+
# Array, Block
|
37
|
+
# Listen to :start_element events on Array elements
|
38
|
+
# Listener
|
39
|
+
# Listen to All events
|
40
|
+
#
|
41
|
+
# Symbol can be one of: :start_element, :end_element,
|
42
|
+
# :start_prefix_mapping, :end_prefix_mapping, :characters,
|
43
|
+
# :processing_instruction, :doctype, :attlistdecl, :elementdecl,
|
44
|
+
# :entitydecl, :notationdecl, :cdata, :xmldecl, :comment
|
45
45
|
#
|
46
46
|
# There is an additional symbol that can be listened for: :progress.
|
47
|
-
# This will be called for every event generated, passing in the current
|
47
|
+
# This will be called for every event generated, passing in the current
|
48
48
|
# stream position.
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
49
|
+
#
|
50
|
+
# Array contains regular expressions or strings which will be matched
|
51
|
+
# against fully qualified element names.
|
52
|
+
#
|
53
|
+
# Listener must implement the methods in SAX2Listener
|
54
|
+
#
|
55
|
+
# Block will be passed the same arguments as a SAX2Listener method would
|
56
|
+
# be, where the method name is the same as the matched Symbol.
|
57
|
+
# See the SAX2Listener for more information.
|
58
|
+
def listen( *args, &blok )
|
59
|
+
if args[0].kind_of? Symbol
|
60
|
+
if args.size == 2
|
61
|
+
args[1].each { |match| @procs << [args[0], match, blok] }
|
62
|
+
else
|
63
|
+
add( [args[0], nil, blok] )
|
64
|
+
end
|
65
|
+
elsif args[0].kind_of? Array
|
66
|
+
if args.size == 2
|
67
|
+
args[0].each { |match| add( [nil, match, args[1]] ) }
|
68
|
+
else
|
69
|
+
args[0].each { |match| add( [ :start_element, match, blok ] ) }
|
70
|
+
end
|
71
|
+
else
|
72
|
+
add([nil, nil, args[0]])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def deafen( listener=nil, &blok )
|
77
|
+
if listener
|
78
|
+
@listeners.delete_if {|item| item[-1] == listener }
|
79
|
+
@has_listeners = false if @listeners.size == 0
|
80
|
+
else
|
81
|
+
@procs.delete_if {|item| item[-1] == blok }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def parse
|
86
|
+
@procs.each { |sym,match,block| block.call if sym == :start_document }
|
87
|
+
@listeners.each { |sym,match,block|
|
88
|
+
block.start_document if sym == :start_document or sym.nil?
|
89
|
+
}
|
90
|
+
context = []
|
91
|
+
while true
|
92
|
+
event = @parser.pull
|
93
|
+
case event[0]
|
94
|
+
when :end_document
|
95
|
+
handle( :end_document )
|
96
|
+
break
|
97
97
|
when :start_doctype
|
98
98
|
handle( :doctype, *event[1..-1])
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
99
|
+
when :end_doctype
|
100
|
+
context = context[1]
|
101
|
+
when :start_element
|
102
|
+
@tag_stack.push(event[1])
|
103
|
+
# find the observers for namespaces
|
104
|
+
procs = get_procs( :start_prefix_mapping, event[1] )
|
105
|
+
listeners = get_listeners( :start_prefix_mapping, event[1] )
|
106
|
+
if procs or listeners
|
107
|
+
# break out the namespace declarations
|
108
|
+
# The attributes live in event[2]
|
109
|
+
event[2].each {|n, v| event[2][n] = @parser.normalize(v)}
|
110
|
+
nsdecl = event[2].find_all { |n, value| n =~ /^xmlns(:|$)/ }
|
111
|
+
nsdecl.collect! { |n, value| [ n[6..-1], value ] }
|
112
|
+
@namespace_stack.push({})
|
113
|
+
nsdecl.each do |n,v|
|
114
|
+
@namespace_stack[-1][n] = v
|
115
|
+
# notify observers of namespaces
|
116
|
+
procs.each { |ob| ob.call( n, v ) } if procs
|
117
|
+
listeners.each { |ob| ob.start_prefix_mapping(n, v) } if listeners
|
118
|
+
end
|
119
|
+
end
|
120
|
+
event[1] =~ Namespace::NAMESPLIT
|
121
|
+
prefix = $1
|
122
|
+
local = $2
|
123
|
+
uri = get_namespace(prefix)
|
124
|
+
# find the observers for start_element
|
125
|
+
procs = get_procs( :start_element, event[1] )
|
126
|
+
listeners = get_listeners( :start_element, event[1] )
|
127
|
+
# notify observers
|
128
|
+
procs.each { |ob| ob.call( uri, local, event[1], event[2] ) } if procs
|
129
|
+
listeners.each { |ob|
|
130
|
+
ob.start_element( uri, local, event[1], event[2] )
|
131
|
+
} if listeners
|
132
|
+
when :end_element
|
133
|
+
@tag_stack.pop
|
134
|
+
event[1] =~ Namespace::NAMESPLIT
|
135
|
+
prefix = $1
|
136
|
+
local = $2
|
137
|
+
uri = get_namespace(prefix)
|
138
|
+
# find the observers for start_element
|
139
|
+
procs = get_procs( :end_element, event[1] )
|
140
|
+
listeners = get_listeners( :end_element, event[1] )
|
141
|
+
# notify observers
|
142
|
+
procs.each { |ob| ob.call( uri, local, event[1] ) } if procs
|
143
|
+
listeners.each { |ob|
|
144
|
+
ob.end_element( uri, local, event[1] )
|
145
|
+
} if listeners
|
146
146
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
147
|
+
namespace_mapping = @namespace_stack.pop
|
148
|
+
# find the observers for namespaces
|
149
|
+
procs = get_procs( :end_prefix_mapping, event[1] )
|
150
|
+
listeners = get_listeners( :end_prefix_mapping, event[1] )
|
151
|
+
if procs or listeners
|
152
|
+
namespace_mapping.each do |ns_prefix, ns_uri|
|
153
|
+
# notify observers of namespaces
|
154
|
+
procs.each { |ob| ob.call( ns_prefix ) } if procs
|
155
|
+
listeners.each { |ob| ob.end_prefix_mapping(ns_prefix) } if listeners
|
156
|
+
end
|
157
|
+
end
|
158
|
+
when :text
|
159
159
|
#normalized = @parser.normalize( event[1] )
|
160
160
|
#handle( :characters, normalized )
|
161
161
|
copy = event[1].clone
|
162
|
-
|
162
|
+
|
163
|
+
esub = proc { |match|
|
164
|
+
if @entities.has_key?($1)
|
165
|
+
@entities[$1].gsub(Text::REFERENCE, &esub)
|
166
|
+
else
|
167
|
+
match
|
168
|
+
end
|
169
|
+
}
|
170
|
+
|
171
|
+
copy.gsub!( Text::REFERENCE, &esub )
|
163
172
|
copy.gsub!( Text::NUMERICENTITY ) {|m|
|
164
173
|
m=$1
|
165
174
|
m = "0#{m}" if m[0] == ?x
|
@@ -167,72 +176,98 @@ module REXML
|
|
167
176
|
}
|
168
177
|
handle( :characters, copy )
|
169
178
|
when :entitydecl
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
end
|
179
|
+
handle_entitydecl( event )
|
180
|
+
when :processing_instruction, :comment, :attlistdecl,
|
181
|
+
:elementdecl, :cdata, :notationdecl, :xmldecl
|
182
|
+
handle( *event )
|
183
|
+
end
|
176
184
|
handle( :progress, @parser.position )
|
177
|
-
|
178
|
-
|
185
|
+
end
|
186
|
+
end
|
179
187
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
188
|
+
private
|
189
|
+
def handle( symbol, *arguments )
|
190
|
+
tag = @tag_stack[-1]
|
191
|
+
procs = get_procs( symbol, tag )
|
192
|
+
listeners = get_listeners( symbol, tag )
|
193
|
+
# notify observers
|
194
|
+
procs.each { |ob| ob.call( *arguments ) } if procs
|
195
|
+
listeners.each { |l|
|
196
|
+
l.send( symbol.to_s, *arguments )
|
197
|
+
} if listeners
|
198
|
+
end
|
191
199
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
200
|
+
def handle_entitydecl( event )
|
201
|
+
@entities[ event[1] ] = event[2] if event.size == 3
|
202
|
+
parameter_reference_p = false
|
203
|
+
case event[2]
|
204
|
+
when "SYSTEM"
|
205
|
+
if event.size == 5
|
206
|
+
if event.last == "%"
|
207
|
+
parameter_reference_p = true
|
208
|
+
else
|
209
|
+
event[4, 0] = "NDATA"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
when "PUBLIC"
|
213
|
+
if event.size == 6
|
214
|
+
if event.last == "%"
|
215
|
+
parameter_reference_p = true
|
216
|
+
else
|
217
|
+
event[5, 0] = "NDATA"
|
218
|
+
end
|
219
|
+
end
|
220
|
+
else
|
221
|
+
parameter_reference_p = (event.size == 4)
|
222
|
+
end
|
223
|
+
event[1, 0] = event.pop if parameter_reference_p
|
224
|
+
handle( event[0], event[1..-1] )
|
225
|
+
end
|
226
|
+
|
227
|
+
# The following methods are duplicates, but it is faster than using
|
228
|
+
# a helper
|
229
|
+
def get_procs( symbol, name )
|
230
|
+
return nil if @procs.size == 0
|
231
|
+
@procs.find_all do |sym, match, block|
|
197
232
|
#puts sym.inspect+"=="+symbol.inspect+ "\t"+match.inspect+"=="+name.inspect+ "\t"+( (sym.nil? or symbol == sym) and ((name.nil? and match.nil?) or match.nil? or ( (name == match) or (match.kind_of? Regexp and name =~ match)))).to_s
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
233
|
+
(
|
234
|
+
(sym.nil? or symbol == sym) and
|
235
|
+
((name.nil? and match.nil?) or match.nil? or (
|
236
|
+
(name == match) or
|
237
|
+
(match.kind_of? Regexp and name =~ match)
|
238
|
+
)
|
239
|
+
)
|
240
|
+
)
|
241
|
+
end.collect{|x| x[-1]}
|
242
|
+
end
|
243
|
+
def get_listeners( symbol, name )
|
244
|
+
return nil if @listeners.size == 0
|
245
|
+
@listeners.find_all do |sym, match, block|
|
246
|
+
(
|
247
|
+
(sym.nil? or symbol == sym) and
|
248
|
+
((name.nil? and match.nil?) or match.nil? or (
|
249
|
+
(name == match) or
|
250
|
+
(match.kind_of? Regexp and name =~ match)
|
251
|
+
)
|
252
|
+
)
|
253
|
+
)
|
254
|
+
end.collect{|x| x[-1]}
|
255
|
+
end
|
221
256
|
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
257
|
+
def add( pair )
|
258
|
+
if pair[-1].respond_to? :call
|
259
|
+
@procs << pair unless @procs.include? pair
|
260
|
+
else
|
261
|
+
@listeners << pair unless @listeners.include? pair
|
262
|
+
@has_listeners = true
|
263
|
+
end
|
264
|
+
end
|
230
265
|
|
231
|
-
|
266
|
+
def get_namespace( prefix )
|
232
267
|
uris = (@namespace_stack.find_all { |ns| not ns[prefix].nil? }) ||
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
268
|
+
(@namespace_stack.find { |ns| not ns[nil].nil? })
|
269
|
+
uris[-1][prefix] unless uris.nil? or 0 == uris.size
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
238
273
|
end
|