rexle 0.6.7 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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