rexle 0.1.5 → 0.2.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 +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