rexle 0.1.5 → 0.2.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 +53 -16
  2. metadata +2 -2
data/lib/rexle.rb CHANGED
@@ -9,7 +9,18 @@ class Rexle
9
9
  end
10
10
 
11
11
  def xpath(path)
12
- @doc.xpath(path).flatten.compact
12
+
13
+ fn_match = path.match(/^(\w+)\(([^\)]+)\)$/)
14
+
15
+ if fn_match.nil? then
16
+ procs = {Array: proc {|x| x.flatten.compact}, String: proc {|x| x}}
17
+ result = @doc.xpath(path)
18
+ procs[result.class.to_s.to_sym].call(result)
19
+ else
20
+ m, xpath_value = r.captures
21
+ method(m.to_sym).call(xpath_value)
22
+ end
23
+
13
24
  end
14
25
 
15
26
  class Element
@@ -41,36 +52,47 @@ class Rexle
41
52
 
42
53
  if xpath_value[0,2] == '//' then
43
54
  s = a[2]
55
+ elsif xpath_value == 'text()' then
56
+ return @value
44
57
  else
58
+
59
+ attribute = xpath_value[/^attribute::(.*)/,1]
60
+ return @attributes[attribute] if attribute
61
+
45
62
  s = a.shift
46
63
  end
47
64
 
48
65
  element_name, condition = s.split(/\[/)
49
66
 
50
67
  if condition then
51
- raw_items = condition.scan(/[\w]+=\'[^\']+\'|and/)
68
+ raw_items = condition.scan(/[\w]+=\'[^\']+\'|and|\d+/)
52
69
 
53
- items = raw_items.map do |x|
54
- name, value = x.split(/=/)
55
- if value then
56
- "h['%s'] == '%s'" % [name,value[1..-2]]
57
- else
58
- name
70
+
71
+
72
+ if raw_items[0][/^\d+$/] then
73
+ attr_search = raw_items[0].to_i
74
+ else
75
+ items = raw_items.map do |x|
76
+ name, value = x.split(/=/)
77
+ if value then
78
+ "h['%s'] == '%s'" % [name,value[1..-2]]
79
+ else
80
+ name
81
+ end
59
82
  end
83
+ attr_search = items.join(' ')
60
84
  end
61
85
 
62
- attr_search = items.join(' ')
63
-
64
86
  end
65
87
 
66
88
  wildcard = element_name[0,2] == '//'
67
- return_elements = @child_lookup.map.with_index.select {|x| x[0][0] == element_name}
89
+ return_elements = @child_lookup.map.with_index.select {|x| x[0][0] == element_name or element_name == '*'}
68
90
 
69
91
  if return_elements.length > 0 then
70
92
  if a.empty? then
71
- return_elements.map {|x| filter(x, attr_search)}
93
+ return_elements.map.with_index {|x,i| filter(x, i+1, attr_search)}
72
94
  else
73
- return_elements.map {|x| filter(x, attr_search){|e| r = e.xpath a.join('/'); r || e }}
95
+ return_elements.map.with_index {|x,i| filter(x, i+1, attr_search){|e| r = e.xpath a.join('/'); r || e }}
74
96
  end
75
97
  else
76
98
  # strip off the 1st element from the XPath
@@ -85,15 +107,26 @@ class Rexle
85
107
  @attributes
86
108
  end
87
109
 
110
+ def text()
111
+ @value
112
+ end
88
113
 
89
- def filter(raw_element, attr_search, &blk)
114
+ def filter(raw_element, i, attr_search, &blk)
90
115
 
91
116
  x = raw_element
92
117
  e = @child_elements[x.last]
93
118
 
94
119
  if attr_search then
95
- h = x[0][1]
96
- block_given? ? blk.call(e) : e if h and eval(attr_search)
120
+ h = x[0][1] # <-- fetch the attributes
121
+ if block_given? then
122
+ blk.call(e)
123
+ else
124
+ if attr_search.is_a? Fixnum then
125
+ e if i == attr_search
126
+ else
127
+ e if h and eval(attr_search)
128
+ end
129
+ end
97
130
  else
98
131
  block_given? ? blk.call(e) : e
99
132
  end
@@ -161,4 +194,8 @@ class Rexle
161
194
  end
162
195
  end
163
196
 
197
+ def count(path)
198
+ @doc.xpath(path).flatten.compact.length
199
+ end
200
+
164
201
  end
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.1.5
4
+ version: 0.2.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-10-20 00:00:00 +01:00
12
+ date: 2010-10-21 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15