rexml 3.2.5 → 3.3.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rexml might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/NEWS.md +251 -2
- data/README.md +10 -1
- data/doc/rexml/tasks/rdoc/element.rdoc +2 -2
- data/doc/rexml/tutorial.rdoc +1358 -0
- data/lib/rexml/attribute.rb +14 -9
- data/lib/rexml/document.rb +1 -1
- data/lib/rexml/element.rb +5 -18
- data/lib/rexml/entity.rb +25 -15
- data/lib/rexml/formatters/pretty.rb +2 -2
- data/lib/rexml/functions.rb +1 -2
- data/lib/rexml/namespace.rb +8 -4
- data/lib/rexml/node.rb +8 -4
- data/lib/rexml/parseexception.rb +1 -0
- data/lib/rexml/parsers/baseparser.rb +281 -240
- data/lib/rexml/parsers/treeparser.rb +9 -14
- data/lib/rexml/parsers/xpathparser.rb +136 -86
- data/lib/rexml/rexml.rb +3 -1
- data/lib/rexml/source.rb +120 -100
- data/lib/rexml/text.rb +6 -4
- data/lib/rexml/xpath_parser.rb +7 -3
- metadata +11 -39
@@ -16,7 +16,6 @@ module REXML
|
|
16
16
|
|
17
17
|
def parse
|
18
18
|
tag_stack = []
|
19
|
-
in_doctype = false
|
20
19
|
entities = nil
|
21
20
|
begin
|
22
21
|
while true
|
@@ -39,17 +38,15 @@ module REXML
|
|
39
38
|
tag_stack.pop
|
40
39
|
@build_context = @build_context.parent
|
41
40
|
when :text
|
42
|
-
if
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
@build_context.
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
)
|
52
|
-
end
|
41
|
+
if @build_context[-1].instance_of? Text
|
42
|
+
@build_context[-1] << event[1]
|
43
|
+
else
|
44
|
+
@build_context.add(
|
45
|
+
Text.new(event[1], @build_context.whitespace, nil, true)
|
46
|
+
) unless (
|
47
|
+
@build_context.ignore_whitespace_nodes and
|
48
|
+
event[1].strip.size==0
|
49
|
+
)
|
53
50
|
end
|
54
51
|
when :comment
|
55
52
|
c = Comment.new( event[1] )
|
@@ -60,14 +57,12 @@ module REXML
|
|
60
57
|
when :processing_instruction
|
61
58
|
@build_context.add( Instruction.new( event[1], event[2] ) )
|
62
59
|
when :end_doctype
|
63
|
-
in_doctype = false
|
64
60
|
entities.each { |k,v| entities[k] = @build_context.entities[k].value }
|
65
61
|
@build_context = @build_context.parent
|
66
62
|
when :start_doctype
|
67
63
|
doctype = DocType.new( event[1..-1], @build_context )
|
68
64
|
@build_context = doctype
|
69
65
|
entities = {}
|
70
|
-
in_doctype = true
|
71
66
|
when :attlistdecl
|
72
67
|
n = AttlistDecl.new( event[1..-1] )
|
73
68
|
@build_context.add( n )
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: false
|
2
|
+
|
2
3
|
require_relative '../namespace'
|
3
4
|
require_relative '../xmltokens'
|
4
5
|
|
@@ -38,108 +39,143 @@ module REXML
|
|
38
39
|
parsed
|
39
40
|
end
|
40
41
|
|
41
|
-
def abbreviate(
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
def abbreviate(path_or_parsed)
|
43
|
+
if path_or_parsed.kind_of?(String)
|
44
|
+
parsed = parse(path_or_parsed)
|
45
|
+
else
|
46
|
+
parsed = path_or_parsed
|
47
|
+
end
|
48
|
+
components = []
|
49
|
+
component = nil
|
50
|
+
while parsed.size > 0
|
51
|
+
op = parsed.shift
|
47
52
|
case op
|
48
53
|
when :node
|
54
|
+
component << "node()"
|
49
55
|
when :attribute
|
50
|
-
|
51
|
-
|
56
|
+
component = "@"
|
57
|
+
components << component
|
52
58
|
when :child
|
53
|
-
|
59
|
+
component = ""
|
60
|
+
components << component
|
54
61
|
when :descendant_or_self
|
55
|
-
|
62
|
+
next_op = parsed[0]
|
63
|
+
if next_op == :node
|
64
|
+
parsed.shift
|
65
|
+
component = ""
|
66
|
+
components << component
|
67
|
+
else
|
68
|
+
component = "descendant-or-self::"
|
69
|
+
components << component
|
70
|
+
end
|
56
71
|
when :self
|
57
|
-
|
72
|
+
next_op = parsed[0]
|
73
|
+
if next_op == :node
|
74
|
+
parsed.shift
|
75
|
+
components << "."
|
76
|
+
else
|
77
|
+
component = "self::"
|
78
|
+
components << component
|
79
|
+
end
|
58
80
|
when :parent
|
59
|
-
|
81
|
+
next_op = parsed[0]
|
82
|
+
if next_op == :node
|
83
|
+
parsed.shift
|
84
|
+
components << ".."
|
85
|
+
else
|
86
|
+
component = "parent::"
|
87
|
+
components << component
|
88
|
+
end
|
60
89
|
when :any
|
61
|
-
|
90
|
+
component << "*"
|
62
91
|
when :text
|
63
|
-
|
92
|
+
component << "text()"
|
64
93
|
when :following, :following_sibling,
|
65
94
|
:ancestor, :ancestor_or_self, :descendant,
|
66
95
|
:namespace, :preceding, :preceding_sibling
|
67
|
-
|
68
|
-
|
69
|
-
string << "::"
|
96
|
+
component = op.to_s.tr("_", "-") << "::"
|
97
|
+
components << component
|
70
98
|
when :qname
|
71
|
-
prefix =
|
72
|
-
name =
|
73
|
-
|
74
|
-
|
99
|
+
prefix = parsed.shift
|
100
|
+
name = parsed.shift
|
101
|
+
component << prefix+":" if prefix.size > 0
|
102
|
+
component << name
|
75
103
|
when :predicate
|
76
|
-
|
77
|
-
|
78
|
-
|
104
|
+
component << '['
|
105
|
+
component << predicate_to_path(parsed.shift) {|x| abbreviate(x)}
|
106
|
+
component << ']'
|
79
107
|
when :document
|
80
|
-
|
108
|
+
components << ""
|
81
109
|
when :function
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
110
|
+
component << parsed.shift
|
111
|
+
component << "( "
|
112
|
+
component << predicate_to_path(parsed.shift[0]) {|x| abbreviate(x)}
|
113
|
+
component << " )"
|
86
114
|
when :literal
|
87
|
-
|
115
|
+
component << quote_literal(parsed.shift)
|
88
116
|
else
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
string << ")"
|
117
|
+
component << "UNKNOWN("
|
118
|
+
component << op.inspect
|
119
|
+
component << ")"
|
93
120
|
end
|
94
121
|
end
|
95
|
-
|
96
|
-
|
122
|
+
case components
|
123
|
+
when [""]
|
124
|
+
"/"
|
125
|
+
when ["", ""]
|
126
|
+
"//"
|
127
|
+
else
|
128
|
+
components.join("/")
|
129
|
+
end
|
97
130
|
end
|
98
131
|
|
99
|
-
def expand(
|
100
|
-
|
101
|
-
|
132
|
+
def expand(path_or_parsed)
|
133
|
+
if path_or_parsed.kind_of?(String)
|
134
|
+
parsed = parse(path_or_parsed)
|
135
|
+
else
|
136
|
+
parsed = path_or_parsed
|
137
|
+
end
|
138
|
+
path = ""
|
102
139
|
document = false
|
103
|
-
while
|
104
|
-
op =
|
140
|
+
while parsed.size > 0
|
141
|
+
op = parsed.shift
|
105
142
|
case op
|
106
143
|
when :node
|
107
|
-
|
144
|
+
path << "node()"
|
108
145
|
when :attribute, :child, :following, :following_sibling,
|
109
146
|
:ancestor, :ancestor_or_self, :descendant, :descendant_or_self,
|
110
147
|
:namespace, :preceding, :preceding_sibling, :self, :parent
|
111
|
-
|
112
|
-
|
113
|
-
|
148
|
+
path << "/" unless path.size == 0
|
149
|
+
path << op.to_s.tr("_", "-")
|
150
|
+
path << "::"
|
114
151
|
when :any
|
115
|
-
|
152
|
+
path << "*"
|
116
153
|
when :qname
|
117
|
-
prefix =
|
118
|
-
name =
|
119
|
-
|
120
|
-
|
154
|
+
prefix = parsed.shift
|
155
|
+
name = parsed.shift
|
156
|
+
path << prefix+":" if prefix.size > 0
|
157
|
+
path << name
|
121
158
|
when :predicate
|
122
|
-
|
123
|
-
|
124
|
-
|
159
|
+
path << '['
|
160
|
+
path << predicate_to_path( parsed.shift ) { |x| expand(x) }
|
161
|
+
path << ']'
|
125
162
|
when :document
|
126
163
|
document = true
|
127
164
|
else
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
string << ")"
|
165
|
+
path << "UNKNOWN("
|
166
|
+
path << op.inspect
|
167
|
+
path << ")"
|
132
168
|
end
|
133
169
|
end
|
134
|
-
|
135
|
-
|
170
|
+
path = "/"+path if document
|
171
|
+
path
|
136
172
|
end
|
137
173
|
|
138
|
-
def
|
139
|
-
|
140
|
-
case
|
174
|
+
def predicate_to_path(parsed, &block)
|
175
|
+
path = ""
|
176
|
+
case parsed[0]
|
141
177
|
when :and, :or, :mult, :plus, :minus, :neq, :eq, :lt, :gt, :lteq, :gteq, :div, :mod, :union
|
142
|
-
op =
|
178
|
+
op = parsed.shift
|
143
179
|
case op
|
144
180
|
when :eq
|
145
181
|
op = "="
|
@@ -156,36 +192,50 @@ module REXML
|
|
156
192
|
when :union
|
157
193
|
op = "|"
|
158
194
|
end
|
159
|
-
left =
|
160
|
-
right =
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
string << right
|
167
|
-
string << " "
|
195
|
+
left = predicate_to_path( parsed.shift, &block )
|
196
|
+
right = predicate_to_path( parsed.shift, &block )
|
197
|
+
path << left
|
198
|
+
path << " "
|
199
|
+
path << op.to_s
|
200
|
+
path << " "
|
201
|
+
path << right
|
168
202
|
when :function
|
169
|
-
|
170
|
-
name =
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
203
|
+
parsed.shift
|
204
|
+
name = parsed.shift
|
205
|
+
path << name
|
206
|
+
path << "("
|
207
|
+
parsed.shift.each_with_index do |argument, i|
|
208
|
+
path << ", " if i > 0
|
209
|
+
path << predicate_to_path(argument, &block)
|
210
|
+
end
|
211
|
+
path << ")"
|
175
212
|
when :literal
|
176
|
-
|
177
|
-
|
178
|
-
string << path.shift.inspect
|
179
|
-
string << " "
|
213
|
+
parsed.shift
|
214
|
+
path << quote_literal(parsed.shift)
|
180
215
|
else
|
181
|
-
|
182
|
-
string << yield( path )
|
183
|
-
string << " "
|
216
|
+
path << yield( parsed )
|
184
217
|
end
|
185
|
-
return
|
218
|
+
return path.squeeze(" ")
|
186
219
|
end
|
220
|
+
# For backward compatibility
|
221
|
+
alias_method :preciate_to_string, :predicate_to_path
|
187
222
|
|
188
223
|
private
|
224
|
+
def quote_literal( literal )
|
225
|
+
case literal
|
226
|
+
when String
|
227
|
+
# XPath 1.0 does not support escape characters.
|
228
|
+
# Assumes literal does not contain both single and double quotes.
|
229
|
+
if literal.include?("'")
|
230
|
+
"\"#{literal}\""
|
231
|
+
else
|
232
|
+
"'#{literal}'"
|
233
|
+
end
|
234
|
+
else
|
235
|
+
literal.inspect
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
189
239
|
#LocationPath
|
190
240
|
# | RelativeLocationPath
|
191
241
|
# | '/' RelativeLocationPath?
|
data/lib/rexml/rexml.rb
CHANGED
@@ -26,10 +26,12 @@
|
|
26
26
|
# - REXML::Document.
|
27
27
|
# - REXML::Element.
|
28
28
|
#
|
29
|
+
# There's also an {REXML tutorial}[doc/rexml/tutorial_rdoc.html].
|
30
|
+
#
|
29
31
|
module REXML
|
30
32
|
COPYRIGHT = "Copyright © 2001-2008 Sean Russell <ser@germane-software.com>"
|
31
33
|
DATE = "2008/019"
|
32
|
-
VERSION = "3.
|
34
|
+
VERSION = "3.3.1"
|
33
35
|
REVISION = ""
|
34
36
|
|
35
37
|
Copyright = COPYRIGHT
|