rexle 0.6.7 → 0.7.0

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.
Files changed (2) hide show
  1. data/lib/rexle.rb +43 -27
  2. metadata +2 -2
data/lib/rexle.rb CHANGED
@@ -11,7 +11,8 @@ include REXML
11
11
  class Rexle
12
12
 
13
13
  def initialize(x=nil)
14
-
14
+ super()
15
+
15
16
  if x then
16
17
  procs = {
17
18
  String: proc {|x| parse_string(x)},
@@ -53,6 +54,7 @@ class Rexle
53
54
  attr_reader :child_lookup
54
55
 
55
56
  def initialize(name=nil, value='', attributes={})
57
+ super()
56
58
  @name, @value, @attributes = name, value, attributes
57
59
  raise "Element name must not be blank" unless name
58
60
  @child_elements = []
@@ -61,11 +63,16 @@ class Rexle
61
63
 
62
64
  def xpath(xpath_value, rlist=[], &blk)
63
65
 
64
- a_path = xpath_value.split('/')
66
+ raw_path, raw_condition = xpath_value.sub(/^\/(?!\/)/,'').match(/([^\[]+)(\[[^\]]+\])?/).captures
67
+ remaining_path = ($').to_s
68
+ a_path = raw_path.split('/')
69
+
70
+ condition = raw_condition if a_path.length <= 1
65
71
 
66
- if xpath_value[0,2] == '//' then
67
- s = a_path[2]
68
- elsif xpath_value == 'text()' then
72
+ if raw_path[0,2] == '//' then
73
+ s = a_path[2] || ''
74
+ condition = raw_condition
75
+ elsif raw_path == 'text()' then
69
76
  a_path.shift
70
77
  return @value
71
78
  else
@@ -73,11 +80,10 @@ class Rexle
73
80
  return @attributes[attribute] if attribute and @attributes and @attributes.has_key?(attribute)
74
81
 
75
82
  s = a_path.shift
76
- end
77
-
78
- elmnt_path = s[/^([\w\*]+\[[^\]]+\])|[\/]+{,2}[^\/]+/]
83
+ end
79
84
 
80
- element_part, condition = elmnt_path.match(/(^@?[^\[]+)?(\[[^\]]+\])?/).captures
85
+ elmnt_path = s[/^([\w\*]+\[[^\]]+\])|[\/]+{,2}[^\/]+/]
86
+ element_part = elmnt_path[/(^@?[^\[]+)?/,1] if elmnt_path
81
87
 
82
88
  if element_part then
83
89
  unless element_part[/^@/] then
@@ -86,11 +92,14 @@ class Rexle
86
92
  condition = element_part
87
93
  element_name = nil
88
94
  end
95
+
89
96
  end
90
97
 
91
- attr_search = format_attributes(condition) if condition
98
+ raw_condition = '' if condition
99
+
100
+ attr_search = format_condition(condition) if condition and condition.length > 0
92
101
 
93
- if xpath_value[0,2] == '//'
102
+ if raw_path[0,2] == '//'
94
103
  return_elements = scan_match(self, element_name, attr_search, condition, rlist)
95
104
  return (xpath_value[/text\(\)$/] ? return_elements.map(&:value) : return_elements)
96
105
  end
@@ -101,13 +110,13 @@ class Rexle
101
110
 
102
111
  if return_elements.length > 0 then
103
112
 
104
- if a_path.empty? then
105
- rlist = return_elements.map.with_index {|x,i| filter(x, i+1, attr_search, &blk)}
106
- rlist = rlist[0] if rlist.length <= 1
113
+ if (a_path + [remaining_path]).join.empty? then
114
+ rlist = return_elements.map.with_index {|x,i| filter(x, i+1, attr_search, &blk)}.compact
115
+ rlist = rlist[0] if rlist.length == 1
107
116
  else
108
-
117
+
109
118
  rlist << return_elements.map.with_index do |x,i|
110
- rtn_element = filter(x, i+1, attr_search){|e| r = e.xpath(a_path.join('/'), &blk); (r || e) }
119
+ rtn_element = filter(x, i+1, attr_search){|e| r = e.xpath(a_path.join('/') + raw_condition.to_s + remaining_path, &blk); (r || e) }
111
120
  next if rtn_element.nil? or (rtn_element.is_a? Array and rtn_element.empty?)
112
121
 
113
122
  if rtn_element.is_a? Array then
@@ -130,7 +139,7 @@ class Rexle
130
139
  new_xpath = xpath_value[/^\/\/\w+\/(.*)/,1]
131
140
 
132
141
  if new_xpath then
133
- self.xpath(new_xpath, rlist,&blk)
142
+ self.xpath(new_xpath + raw_condition.to_s + remaining_path, rlist,&blk)
134
143
  end
135
144
  end
136
145
 
@@ -185,10 +194,6 @@ class Rexle
185
194
  procs[s.class.to_s.to_sym].call(s)
186
195
  end
187
196
 
188
- def leaf_value(e, path)
189
- (path[/\//] ? e.xpath(path).first : e).value
190
- end
191
-
192
197
  def root() self end
193
198
  def text(s='')
194
199
  if s.empty? then
@@ -213,14 +218,14 @@ class Rexle
213
218
  out
214
219
  end
215
220
 
216
- def format_attributes(condition)
217
- raw_items = condition[1..-1].scan(/\'[^\']*\'|and|or|\d+|[!=]+|[@\w\.]+/)
218
-
221
+ def format_condition(condition)
222
+ raw_items = condition[1..-1].scan(/\'[^\']*\'|and|or|\d+|[!=]+|[@\w\.\/]+/)
223
+
219
224
  if raw_items[0][/^\d+$/] then
220
225
  return raw_items[0].to_i
221
226
  else
222
227
 
223
- andor_items = raw_items.map.with_index.select{|x,i| x[/and|or/]}.map{|x| [x.last, x.last + 1]}.flatten
228
+ andor_items = raw_items.map.with_index.select{|x,i| x[/\band\b|\bor\b/]}.map{|x| [x.last, x.last + 1]}.flatten
224
229
 
225
230
  indices = [0] + andor_items + [raw_items.length]
226
231
 
@@ -229,6 +234,7 @@ class Rexle
229
234
  cons_items = indices.each_cons(2).map{|x,y| raw_items.slice(x...y)}
230
235
 
231
236
  items = cons_items.map do |x|
237
+
232
238
  if x.length >= 3 then
233
239
  x[1] = '==' if x[1] == '='
234
240
  "h['%s'] %s %s" % x
@@ -246,9 +252,15 @@ class Rexle
246
252
  if x.length >= 3 then
247
253
  x[1] = '==' if x[1] == '='
248
254
  if x[0] != '.' then
249
- "name == '%s' and value %s %s" % [x[0], x[1], x[2]]
255
+ if x[0][/\//] then
256
+ path, value = x.values_at(0,-1)
257
+
258
+ "e.xpath('#{path}').first.value == #{value}"
259
+ else
260
+ "name == '%s' and value %s %s" % [x[0], x[1], x[2]]
261
+ end
250
262
  else
251
- "leaf_value(e) %s %s" % [x[1], x[2]]
263
+ "e.value %s %s" % [x[1], x[2]]
252
264
  end
253
265
  else
254
266
  x
@@ -307,8 +319,11 @@ class Rexle
307
319
  block_given? ? blk.call(e) : e
308
320
  elsif attr_search[/^e\.value/] and eval(attr_search)
309
321
  block_given? ? blk.call(e) : e
322
+ elsif attr_search[/^e\.xpath/] and eval(attr_search)
323
+ block_given? ? blk.call(e) : e
310
324
  end
311
325
  else
326
+
312
327
  block_given? ? blk.call(e) : e
313
328
  end
314
329
 
@@ -318,6 +333,7 @@ class Rexle
318
333
 
319
334
  class Elements
320
335
  def initialize(elements=[])
336
+ super()
321
337
  @elements = elements
322
338
  end
323
339
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rexle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.7
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors: []
7
7
 
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-12-10 00:00:00 +00:00
12
+ date: 2010-12-14 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency