rubysl-rexml 1.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|