rexleparser 0.9.9 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3059b4fd1544e6c16167934dbc60e77c82c0bf57674e0d99e71c39b96909efb1
4
- data.tar.gz: 6f3377d006cd852abe4b88881a320207579d138fbadf5e8aa830a3d4ca24d598
3
+ metadata.gz: a6291ec758a59d1737240656c502a96250c5fe6cdd230a452c220ba34c17f091
4
+ data.tar.gz: c9edbdc47b4e728598407ddd23da8d5622ed699069061742497d3017477e25bc
5
5
  SHA512:
6
- metadata.gz: f2ddf0f05e84df521185a1606aa98b6a745902e2d35235d2ff6948e430ced3cfa2772aa1944191b00c8a045b16c58be884ce0a2f5dcdc7ec2e4e7cc078c5caa6
7
- data.tar.gz: 8ef7aae9fc024a71d8ab79254f6ca7abb6d301ebd02696e15ea5138ab68074b2f57ebd8166a4f4421c61d24db2f94101654d753bf4af800ef593ae44c99d06ff
6
+ metadata.gz: 2665fb624f0b3fee4e4304c304c093900685e6708bfc62209fa54a0f0108e7e195844285fa7a677a91d83f0ee72c306ca8f785052cd7d6c51dba3ab1ea3950b9
7
+ data.tar.gz: 8c7d22a214d798f867d670c300d2b61c2235a17c437823ac7f5978dcb3c80015d3887dfc2f7f22b421d58d6b3b321eaa327ac931cb0448c06c1d1f71f70640ae
checksums.yaml.gz.sig CHANGED
Binary file
data/lib/rexleparser.rb CHANGED
@@ -7,20 +7,20 @@
7
7
  class Attributes < Hash
8
8
 
9
9
  class Value < String
10
-
10
+
11
11
  def initialize(value)
12
12
  #jr2020-04-30 super(value.gsub("'", '&apos;'))
13
13
  super(value)
14
14
  end
15
-
15
+
16
16
  def <(val2)
17
17
  self.to_f < val2.to_f
18
- end
19
-
18
+ end
19
+
20
20
  def >(val2)
21
21
  self.to_f > val2.to_f
22
22
  end
23
-
23
+
24
24
  def inspect()
25
25
  super().gsub('&lt;','<',).gsub('&gt;','>').gsub('&pos;',"'")
26
26
  end
@@ -28,207 +28,256 @@ class Attributes < Hash
28
28
  def to_s(unescape: true)
29
29
  unescape ? self.gsub('&amp;','&').gsub('&pos;',"'") : self
30
30
  end
31
-
32
- end
33
-
31
+
32
+ end
33
+
34
34
  def initialize(h={})
35
35
  super().merge! h
36
36
  end
37
-
37
+
38
38
  def []=(k,v)
39
39
  super(k, k != :class ? Value.new(v) : v)
40
40
  end
41
41
 
42
+ def delete(key=nil)
43
+
44
+ if key then
45
+ super(key)
46
+ else
47
+ keys.each {|key| super(key)}
48
+ end
49
+
50
+ end
51
+
42
52
  def merge(h)
43
53
 
44
- h2 = h.inject({}) do |r, kv|
54
+ h2 = h.inject({}) do |r, kv|
45
55
  k, raw_v = kv
46
56
  v = raw_v.is_a?(String) ? Value.new(raw_v) : raw_v
47
- r.merge(k => v)
57
+ r.merge(k => v)
48
58
  end
49
-
59
+
50
60
  super(h2)
51
-
61
+
52
62
  end
53
63
  end
54
64
 
65
+
55
66
  class RexleParserException < Exception
56
67
  end
57
68
 
58
69
  class RexleParser
59
70
 
60
- attr_reader :instructions, :doctype, :to_a
61
-
62
- def initialize(raw_s)
71
+ attr_reader :stack
63
72
 
64
- super()
65
- s = raw_s.clone.strip
66
- return if s.empty?
73
+ def initialize(raws, debug: false)
67
74
 
75
+ s = raws.strip
76
+ @debug = debug
77
+ @a = []
78
+ @stack = []
79
+
68
80
  raw_xml, raw_instrctns = if s.lines.first =~ /<?xml/ then
69
- s.split(/(?=\?>\s*<\w)/,2).reverse
81
+ s.split(/(?<=\?>)/,2).reverse
70
82
  else
71
83
  s
72
84
  end
85
+ puts 'raw_xml: ' + raw_xml.inspect if @debug
73
86
  @instructions = raw_instrctns ? \
74
87
  raw_instrctns.scan(/<\?([\w-]+) ([^\?]+)/) : []
75
88
  @doctype = s.slice!(/<!DOCTYPE html>\n?/) if s.lines.first =~ /<\!DOCTYPE/
76
- @to_a = reverse(parse_node(raw_xml.strip.reverse))
89
+
90
+ # scancom is run twice because we 1st check for comment tags and then cdata tags
91
+ @a = parse(scancom(scancom(raw_xml), type: :cdata)).flatten(1)
77
92
 
78
93
  end
79
94
 
80
- private
81
-
82
-
83
- def scan_next(r, tagname)
84
-
85
- j = tagname
86
-
87
- if r[0] == '>' then
88
-
89
- # end tag match
90
- tag = r[/^>[^<]+</]
91
-
92
- if tag[1][/[ \w"']/] and tag[-2] != '/' then
93
-
94
- # is it the end tag to match the start tag?
95
- tag = r.slice!(/^>[^<]+</)
96
- end_tag = tag[/^>[^>]*#{j}<$/]
97
-
98
- if end_tag then
99
-
100
- j = nil
101
- return [:end_tag, end_tag]
102
-
103
- elsif tag[/^>[^>]*\w+<$/] then
104
- # broken tag found
105
- broken_tag = tag
106
- return [:child, [nil, [], broken_tag]] if broken_tag
107
- else
108
-
109
- text, newtag = tag.sub('>',';tg&').split(/>/,2)
110
-
111
- if newtag then
112
- tag = newtag
113
- r.prepend '>' + tag
114
- end
115
-
116
- return [:child, text]
117
- end
118
- elsif r[0,3] == '>--' then # comment tag found
95
+ def to_a()
96
+ @a
97
+ end
119
98
 
120
- r.slice!(0,3)
121
- i = r =~ /(\-\-!<)/
122
- s = r.slice!(0,i)
123
- r.slice!(0,4)
99
+ private
100
+
101
+ def ehead(raws)
102
+
103
+ s = raws.lstrip
104
+ puts '_s: ' + s.inspect if @debug
105
+ # fetch the element head
106
+ tag = s =~ /<[^>]+\/?>/
107
+ s2 = s[tag+1..-1]
108
+ tagb = s2 =~ />/
109
+ return unless tag
110
+
111
+ len = tagb+1-tag
112
+
113
+ if @debug then
114
+ puts 'ehead()/detail: ' + [tag, tagb, len, s[tag,len+1]].inspect
115
+ end
124
116
 
125
- tagname, content = ['-!',s]
117
+ [s[tag,len+1], s[len+1..-1]]
126
118
 
127
- return [:child, [">#{tagname}<", [content], ">#{tagname}/<"]]
119
+ end
128
120
 
129
- elsif r[0,3] == '>]]' then # CDATA tag found
121
+ def get_attributes(raw_attributes)
122
+
123
+ r1 = /([\w\-:\(\)]+\='[^']*)'/
124
+ r2 = /([\w\-:\(\)]+\="[^"]*)"/
125
+
126
+ r = raw_attributes.scan(/#{r1}|#{r2}/).map(&:compact)\
127
+ .flatten.inject(Attributes.new) do |r, x|
128
+ attr_name, raw_val = x.split(/=/,2)
129
+ val = attr_name != 'class' ? raw_val[1..-1] : raw_val[1..-1].split
130
+ r.merge(attr_name.to_sym => val)
131
+ end
130
132
 
131
- r.slice!(0,3)
132
- i = r =~ /(\[ATADC\[!<)/
133
- s = r.slice!(0,i)
134
- r.slice!(0,9)
133
+ return r
134
+ end
135
135
 
136
- tagname, content = ['[!',s]
136
+ def parse(raws, a=[], cur=nil)
137
137
 
138
- return [:child, [">#{tagname}<", [content], ">#{tagname}/<"]]
138
+ s = raws #.lstrip
139
+
140
+ if @debug then
141
+ puts '.parse() s: ' + s.inspect[0..600]
142
+ puts '.parse() a: ' + a.inspect[0..699]
143
+ puts '.parse() cur: ' + cur.inspect[0..799]
144
+ end
139
145
 
140
- elsif tag[/>\/|\/<$/] or tag[/^>.*[\w!]+\/<$/] then
146
+ # if self-closing tag
147
+ if s =~ /^<[^<]+\/>/ then
141
148
 
142
- return [:newnode]
149
+ tag = s[/^<[^<]+\/>/]
150
+ puts 'parse() self-closing/tag: ' + tag.inspect if @debug
151
+ tail = $'
152
+
153
+ if @debug then
154
+ puts 'parse() self-closing tag found'
155
+ puts 'parse()/tail: ' + tail.inspect
156
+ end
157
+
158
+ a2 = parsetag(tag)
159
+ puts '_a: ' + a.inspect if @debug
160
+ cur ? a.last << a2 : a << a2
161
+
162
+ parse(tail, a, cur)
163
+
164
+ # is it the head?
165
+ elsif (s =~ /^<[^\/>]+>/) == 0 then
166
+
167
+ puts 'parse()/head found' if @debug
168
+
169
+ tag, tail = ehead(s)
170
+
171
+ if @debug then
172
+ puts 'parse() tag: ' + tag.inspect
173
+ puts 'parse() tail: ' + tail.inspect
174
+ end
175
+ # add it to the list
176
+ a2 = parsetag(tag)
143
177
 
178
+ puts '_cur: ' + cur.inspect if @debug
179
+ if cur then
180
+ cur << a2
181
+ cur2 = cur.last
144
182
  else
183
+ a << a2
184
+ cur2 = a.last
185
+ end
145
186
 
146
- r.sub!('>',';tg&')
147
- i = r =~ />(?:[\-\/"'\w]|\]\])/ # collect until a tag is found or a CDATA element
148
- text = r.slice!(0,i)
149
-
150
- return [:child, text] if text
151
-
152
- end # end of tag match
153
-
154
- else
155
-
156
- # it's a text value
157
- i = r =~ />(?:[\-\/"'\w]|\]\])/ # collect until a tag is found or a CDATA element
158
- text = r.slice!(0,i)
159
-
160
- return [:child, text] if text
161
- end
162
- end
187
+ puts '_a: ' + a.inspect if @debug
163
188
 
164
- def parse_node(r, j=nil)
189
+ # add it to the stack
190
+ @stack.push cur2
165
191
 
166
- return unless r.length > 0
167
- tag = r.slice!(/^>[^<]+</) if (r =~ /^>[^<]+</) == 0
168
- tagname = tag[/([\w!:]+)\/?<$/,1]
192
+ parse(tail, a, cur2)
193
+
194
+ elsif (s =~ /^[^<]/) == 0
169
195
 
170
- # self closing tag?
171
- if tag[/^>\/.*#{tagname}<$/m] then
172
- return [">/#{tagname}<", [], "#{tag.sub(/>\//,'>')}"]
173
- end
196
+ puts 'parse() we have text!' if @debug
197
+ text = raws[/[^<]+/m] #
198
+ remaining = $'
199
+
200
+ if @debug then
201
+ puts 'parse() text: ' + text.inspect
202
+ puts 'cur tag: ' + cur[0].inspect
203
+ end
204
+
205
+ cur << if cur[0][0] == '!' then
206
+ text.gsub('&lt;','<').gsub('&gt;','>').gsub('&amp;','&')
207
+ else
208
+ text.gsub(/>/,'&gt;').gsub(/</, '&lt;')
209
+ end
174
210
 
175
- start_tag, children, end_tag = tag, [], nil
211
+ puts 'remaining: ' + remaining.inspect if @debug
212
+ parse(remaining, a, cur) if remaining.length > 0
213
+
214
+
215
+ # is it a closing tag?
216
+ elsif s =~ /^\s?<\/\w+>/m
217
+
218
+ tail = s[/^\s*<\/\w+>(.*)/m,1]
219
+
220
+ if @debug then
221
+ puts 'parse()/closing tag ' + s[/^\s*<\/\w+>/].inspect
222
+ puts '>a: ' + a.inspect
223
+ end
224
+
225
+ @stack.pop
226
+ #a << []
227
+ parse(tail, a, @stack.last)
228
+
229
+ elsif s.empty? and @stack.length > 0
230
+
231
+ puts 'parse() no end tag!' if @debug
176
232
 
177
- unless start_tag[1..-3][/\w+$/] then
178
- raise RexleParserException, 'invalid closing tag found ' + \
179
- start_tag.reverse + '; context: ' + r[0..120].reverse.inspect
180
233
  end
181
234
 
182
- until end_tag do
183
-
184
- key, res = scan_next r, tagname
185
-
186
- case key
187
- when :end_tag
188
- end_tag = res
189
- r2 = [start_tag, children, end_tag]
190
- end_tag = nil
191
-
192
- return r2
193
- when :child
194
- children << res
195
- when :newnode
196
- children << parse_node(r, tagname)
197
- else
198
- break
199
- end
200
- end
235
+ return a
201
236
 
202
- [start_tag, children, end_tag]
203
237
  end
204
238
 
205
- def get_attributes(raw_attributes)
206
-
207
- r1 = /([\w\-:\(\)]+\='[^']*)'/
208
- r2 = /([\w\-:\(\)]+\="[^"]*)"/
209
-
210
- r = raw_attributes.scan(/#{r1}|#{r2}/).map(&:compact)\
211
- .flatten.inject(Attributes.new) do |r, x|
212
- attr_name, raw_val = x.split(/=/,2)
213
- val = attr_name != 'class' ? raw_val[1..-1] : raw_val[1..-1].split
214
- r.merge(attr_name.to_sym => val)
239
+ # we parse the tag because it contains more than just the name it often contains attributes
240
+ #
241
+ def parsetag(s)
242
+
243
+ puts 'parsetag:' + s.inspect if @debug
244
+ rawtagname, rawattr = s[1..-2].sub(/\/$/,'').match(/^(\w+) *(.*)/)\
245
+ .values_at(1,2)
246
+
247
+ tagname = case rawtagname.to_sym
248
+ when :_comment
249
+ '!-'
250
+ when :_cdata
251
+ '!['
252
+ else
253
+ rawtagname
215
254
  end
216
255
 
217
- return r
256
+ [tagname, get_attributes(rawattr)]
218
257
  end
219
258
 
220
- def reverse(raw_obj)
259
+ def scancom(s, type=:comment)
221
260
 
222
- return unless raw_obj
223
- obj = raw_obj.clone
224
- return obj.reverse! if obj.is_a? String
261
+ tag1 = ['<!--', '-->', 'comment', '<!--']
262
+ tag2 = ['<![CDATA[', '\]\]>', 'cdata', '\<!\[CDATA\[']
263
+ tag = type == :comment ? tag1 : tag2
225
264
 
226
- tag = obj.pop.reverse
265
+ #puts 'tag: ' + tag.inspect
266
+ istart = s =~ /#{tag[3]}/
267
+ return s unless istart
227
268
 
228
- children = obj[-1]
269
+ iend = s =~ /#{tag[1]}/
270
+ comment ="<_%s>%s</_%s>" % [tag[2], s[istart+tag[0].length.. iend-1].gsub('&','&amp;').gsub('<','&lt;').gsub('>','&gt;'), tag[2]]
229
271
 
230
- r = children.reverse.map {|x| reverse(x)}
272
+ if @debug then
273
+ puts 'comment: ' + comment.inspect
274
+ # construct the new string
275
+ puts 'istart: ' + istart.inspect
276
+ end
277
+
278
+ s3 = s[0,istart].to_s + comment + s[iend+3..-1]
279
+ scancom(s3, type)
231
280
 
232
- return [tag[/[!\-\w:\[]+/], get_attributes(tag), *r]
233
281
  end
282
+
234
283
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rexleparser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.9
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Robertson
@@ -10,32 +10,33 @@ bindir: bin
10
10
  cert_chain:
11
11
  - |
12
12
  -----BEGIN CERTIFICATE-----
13
- MIIEXjCCAsagAwIBAgIBATANBgkqhkiG9w0BAQsFADAsMSowKAYDVQQDDCFnZW1t
14
- YXN0ZXIvREM9amFtZXNyb2JlcnRzb24vREM9ZXUwHhcNMjEwNDAxMTI1NDA1WhcN
15
- MjIwNDAxMTI1NDA1WjAsMSowKAYDVQQDDCFnZW1tYXN0ZXIvREM9amFtZXNyb2Jl
16
- cnRzb24vREM9ZXUwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC9tf0T
17
- BYEECADFGYQisEHfQBwZtTbhsjWGAsDG1CCEg+Zje9gQIwCPVPUYtEiZkmPtb2en
18
- YQ0gdCvrSdaxyeP+O7UnN2sR/Rb0G/4Nx3gzY5e+k1PeZ+YEHhehzF/CjpxCpief
19
- Mhi2HgToCQ71U1iyUT3Squb3CBA6vwLJI6MMh71GWU01aqrMT/l9W3vN54SAZ5i7
20
- Ud9nVF4JsMXwHyzikv5MH6WwIOzMhqKMUxaAeeGAlFN3u2G2DGW+7fd9/z5zpD6S
21
- XJEvqjllf5fetAk77Lvw7hPfK0gHJHwTva7k87K704pYgKvi8bAwcnhk/aHXgyON
22
- D42nLpNYipRRVTXiNXxo9svPTSDGsee5e0prmpC/U9bD2T4SxCrM7VvfVWXbhhEX
23
- 47iZDeo2KllKmocjA02vfqtbaQXEATi3fSz/pdRpCr1g/Rd/JdAjRnxHgUu1q1TU
24
- JU99/sfjaxBGvbL+C20cfMgdXdPrkGPNsiEDqfxK5IIBfaob8cp6jzKNDosCAwEA
25
- AaOBijCBhzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUgG4OM1TJ
26
- YfZh1FAIhnVN+TXDs64wJgYDVR0RBB8wHYEbZ2VtbWFzdGVyQGphbWVzcm9iZXJ0
27
- c29uLmV1MCYGA1UdEgQfMB2BG2dlbW1hc3RlckBqYW1lc3JvYmVydHNvbi5ldTAN
28
- BgkqhkiG9w0BAQsFAAOCAYEACka8bLaU+wG55T9M2lqOrmXMsKpHQ5xtmSQk29OJ
29
- 4FUZ4aJEhTYxzJosvMNpauZVyrk+KyF/8uuGz5CfG/aPbOboB9+EIsmIcvRZ696M
30
- BUXc6OuHE8SL0C9yuB9PloIZy2nxrRENFSV5xxyMS04bcaQjKCqtKw69+QT6lbra
31
- iAU2EIebKyy0UIbrJSBIDKfig9KMEUrXvFUR4hu0lWpeT1bwq4sYeIeZNcg3v/y3
32
- EbV3QK7AumvKgYvaz7iTu+9FKWT7AqIOH9wuPNPeXDLgyuKhLjdMaugz0wy6RYhT
33
- Q8tgppTgSzQP8XwMg3xsaM+gWHbRLy8tO+3dkWTPN1m0xETWlSWFCiyi6oq8G4wC
34
- t4pClPXscWrfmQa/u189WCF/O5BbsElrKQqx0vjq73l2apKjN9xViJi4LrEsZTuz
35
- cF/nszU+U7PJ1WnQ+W7QTqoViru4N0S9bwi3YV5F5NPPeVnnrtmC2yruRfgTCI4b
36
- 3nEas0DJDZbQSkPP1mVcybEA
13
+ MIIEljCCAv6gAwIBAgIBATANBgkqhkiG9w0BAQsFADBIMRIwEAYDVQQDDAlnZW1t
14
+ YXN0ZXIxHjAcBgoJkiaJk/IsZAEZFg5qYW1lc3JvYmVydHNvbjESMBAGCgmSJomT
15
+ 8ixkARkWAmV1MB4XDTIzMDMwNzEyNDM0MVoXDTI0MDMwNjEyNDM0MVowSDESMBAG
16
+ A1UEAwwJZ2VtbWFzdGVyMR4wHAYKCZImiZPyLGQBGRYOamFtZXNyb2JlcnRzb24x
17
+ EjAQBgoJkiaJk/IsZAEZFgJldTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoC
18
+ ggGBAMXdVvebuQa1+janwRx6yjABUKs2WSd6ns81LBol0KgH8Lmjj5CdIJHK/IFZ
19
+ pcjvbJCSNJS9eREO4RnHkJTUpYE6xgTboCsSMdTpJU3MK2Y+PHXQu5YJHBQQBWSe
20
+ LORpuKuhQuhU+oQgxnuszksIO1UBU+Xh0D5dntbWpiFBGPzTctoBTtJqBdClZwXc
21
+ s1mAmXhAkeK2hmT0Rw/IY2CqZAMeMbrVZBaqazYvqXvfDisRPMMZVZMz9al3w6IE
22
+ L9E4tDbU1sExjUgVGB+BIV6SIG5kYrOzpDKnZXhvPbmUR08iZeTe0IpUIFMIYPIy
23
+ kPJxO45OaxLwnabV+jC38P2CV4Pbx6dij/M/mWisD/az4kzmw1kGUMGJiPIn/XRX
24
+ mLOOxuCQxHDts+7tvD+/wTtSIxklsvVKz49QH1ybNrOdoYQuB8qNnLPFzKFr+5SC
25
+ ojuaJ45mf/Uv3Orps8LXj8WmOBvbJWC1/Lglhy+hhGV/7gh1EKVMpx6AwKcJ1+85
26
+ R19PMQIDAQABo4GKMIGHMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
27
+ BBQiPSrne0dHxLynj/1izBmEwv/lkTAmBgNVHREEHzAdgRtnZW1tYXN0ZXJAamFt
28
+ ZXNyb2JlcnRzb24uZXUwJgYDVR0SBB8wHYEbZ2VtbWFzdGVyQGphbWVzcm9iZXJ0
29
+ c29uLmV1MA0GCSqGSIb3DQEBCwUAA4IBgQBWIQG28MQXuVSHsAw/rQuaE1FpOmz0
30
+ AXWhHK1oDWxkoPTBIoLil2M2PI3htcBBRLUzyli9XFvqjzuO+J8LpWqs2iddxjXP
31
+ 3xtUg0h+0urVRk00xwsnPLppwT7VxvycQifN31En8rMEzd24V5FKkn90brdokVQC
32
+ 5aL/9LD3S5k3t4AyUcGeOFuU+k87lEz8bzKk2wjOjzpgxjNyqeK6h0iFeA94rhnp
33
+ HPaebr7ytgAR3dKU/Zr/gmZdQroli86LaOqGK1AJQ9E1RFBKwKluNa27dR3VyqBA
34
+ VG1Z/9QNxm0ivqKr7samwkNUGiql+s4CPZndbJD/hmDDdmCtYf1mywCAUOh+DrfU
35
+ iKwWhO5Qmo/RUOvr0a4KtP5i0N7qY1LFMSCpfCRTS9zTlfTIjs1ipAnWhLcqp5Js
36
+ NMSYHad41dFYLrVyE7mdZdIVlFqIdG+V1x7iY+zPpg7FS/8EUnK5zUxMC0YoLeK2
37
+ hcHycb1NL9Ujb7onXEop5Dobym6xO6V+yBY=
37
38
  -----END CERTIFICATE-----
38
- date: 2022-01-15 00:00:00.000000000 Z
39
+ date: 2023-03-07 00:00:00.000000000 Z
39
40
  dependencies: []
40
41
  description:
41
42
  email: digital.robertson@gmail.com
@@ -63,8 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
64
  - !ruby/object:Gem::Version
64
65
  version: '0'
65
66
  requirements: []
66
- rubyforge_project:
67
- rubygems_version: 2.7.10
67
+ rubygems_version: 3.4.6
68
68
  signing_key:
69
69
  specification_version: 4
70
70
  summary: Rexleparser is an XML parser used by the Rexle gem
metadata.gz.sig CHANGED
@@ -1,3 +1,3 @@
1
- ��0J��g%r��3���ֺ�<�
2
- 6I���db
3
- �6إ�wth
1
+ ,����<�a��1�����$n�]�� ᆧAWεp����J���z {0aM��p�٥tP�u���,k���l �ygܖ|8��P�t"}����ej
2
+ +֢��PJ{ݍ��}ׄ��vj a�m,�G��]��ӡ� ���h&r����C*�r��3I=�i��O�ɂ�7�]~��?����CH��Z��j���*�9���ե�ӱM��R+��a����n�3ͣJ��Lm�,��mU&���2>@G���a�OQ�0�b�&��%�.��
3
+ |d�!lDO#�3{�oV��+�(��7<j��pc� "�z���֤�ϗ'�m�si�0�}��y��eP1�:���Dcյ���6=�R,�s�{�7�d}�jj�h�f�j��