vcdom 0.3.0 → 0.3.1
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.
- data/README.rdoc +33 -0
- data/lib/vcdom/attr.rb +3 -3
- data/lib/vcdom/character_data.rb +8 -1
- data/lib/vcdom/document.rb +27 -11
- data/lib/vcdom/element.rb +87 -1
- data/lib/vcdom/node.rb +29 -1
- data/lib/vcdom/parent.rb +9 -0
- data/lib/vcdom/{xml_parser.rb → xml_ls/xml_parser.rb} +123 -94
- data/lib/vcdom/{xml_serializer.rb → xml_ls/xml_serializer.rb} +1 -1
- data/lib/vcdom/xml_ls.rb +42 -0
- data/lib/vcdom/xpath/evaluative.rb.old +73 -0
- data/lib/vcdom/xpath/internal/command.rb +121 -0
- data/lib/vcdom/xpath/internal/evaluator.rb +307 -0
- data/lib/vcdom/xpath/internal/expr.rb +35 -0
- data/lib/vcdom/xpath/internal/parser.rb +333 -0
- data/lib/vcdom/xpath/internal/value.rb +342 -0
- data/lib/vcdom/xpath/xpath_evaluator_mod.rb +32 -0
- data/lib/vcdom/xpath/xpath_exception.rb +23 -0
- data/lib/vcdom/xpath/xpath_expression.rb +79 -0
- data/lib/vcdom/xpath/xpath_ns_resolver.rb +36 -0
- data/lib/vcdom/xpath/xpath_result.rb +104 -0
- data/lib/vcdom/xpath.rb +15 -0
- data/test/main_test_1.8.rb.old +1 -0
- data/test/main_test_1.9.rb.old +25 -0
- data/test/test_main.rb +6 -0
- data/test/test_parsing.rb +41 -0
- data/test/test_xpath.rb +266 -0
- metadata +34 -25
@@ -0,0 +1,73 @@
|
|
1
|
+
# coding : utf-8
|
2
|
+
|
3
|
+
module VCDOM
|
4
|
+
module XPath
|
5
|
+
|
6
|
+
module Evaluative
|
7
|
+
|
8
|
+
def create_expression( expression, resolver )
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_ns_resolver( node_resolver )
|
12
|
+
end
|
13
|
+
|
14
|
+
def evaluate( expression, context_node, resolver, type, result )
|
15
|
+
self.create_expression( expression, resolver ).evaluate( context_node, type, result )
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
class Expression
|
21
|
+
def evaluate( context_node, type, result )
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class NSResolver
|
26
|
+
def lookup_namespace_uri( prefix )
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class XPathResult
|
31
|
+
# XPathResultType
|
32
|
+
ANY_TYPE = 0
|
33
|
+
NUMBER_TYPE = 1
|
34
|
+
STRING_TYPE = 2
|
35
|
+
BOOLEAN_TYPE = 3
|
36
|
+
UNORDERED_NODE_ITERATOR_TYPE = 4
|
37
|
+
ORDERED_NODE_ITERATOR_TYPE = 5
|
38
|
+
UNORDERED_NODE_SNAPSHOT_TYPE = 6
|
39
|
+
ORDERED_NODE_SNAPSHOT_TYPE = 7
|
40
|
+
ANY_UNORDERED_NODE_TYPE = 8
|
41
|
+
FIRST_ORDERED_NODE_TYPE = 9
|
42
|
+
|
43
|
+
def result_type
|
44
|
+
end
|
45
|
+
def number_value
|
46
|
+
end
|
47
|
+
def string_value
|
48
|
+
end
|
49
|
+
|
50
|
+
def boolean_value
|
51
|
+
end
|
52
|
+
|
53
|
+
def single_node_value
|
54
|
+
end
|
55
|
+
def invalid_iterator_state
|
56
|
+
end
|
57
|
+
def snapshot_length
|
58
|
+
end
|
59
|
+
|
60
|
+
def iterate_next()
|
61
|
+
end
|
62
|
+
def snapshot_item( index )
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Namespace < Node
|
67
|
+
XPATH_NAMESPACE_NODE = 13
|
68
|
+
def owner_element
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# coding : utf-8
|
2
|
+
|
3
|
+
module VCDOM::XPath::Internal # :nodoc:
|
4
|
+
|
5
|
+
class AbstractCommand # :nodoc:
|
6
|
+
def is_value?; false end
|
7
|
+
def is_expr?; false end
|
8
|
+
def is_command?; true end
|
9
|
+
|
10
|
+
def to_s()
|
11
|
+
"XPathCommand(#{command_type})"
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
class AbstractOperationCommand < AbstractCommand # :nodoc:
|
17
|
+
def initialize( operation_name )
|
18
|
+
@operation_name = operation_name
|
19
|
+
end
|
20
|
+
attr_reader :operation_name
|
21
|
+
|
22
|
+
def to_s()
|
23
|
+
"XPathCommand(#{command_type}, #{operation_name})"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class OperationUnaryCommand < AbstractOperationCommand # :nodoc:
|
28
|
+
def command_type; :operation_unary end
|
29
|
+
end
|
30
|
+
|
31
|
+
class OperationBinaryCommand < AbstractOperationCommand # :nodoc:
|
32
|
+
def command_type; :operation_binary end
|
33
|
+
end
|
34
|
+
|
35
|
+
@operation_unary_commands = {
|
36
|
+
:"-@" => OperationUnaryCommand.new( :"-@" ),
|
37
|
+
:"+" => OperationBinaryCommand.new( :"+" ),
|
38
|
+
:"-" => OperationBinaryCommand.new( :"-" ),
|
39
|
+
:"*" => OperationBinaryCommand.new( :"*" ),
|
40
|
+
:"div" => OperationBinaryCommand.new( :"/" ),
|
41
|
+
:"mod" => OperationBinaryCommand.new( :"%" ),
|
42
|
+
:"=" => OperationBinaryCommand.new( :"==" ),
|
43
|
+
:"!=" => OperationBinaryCommand.new( :"neq?" ),
|
44
|
+
:"<" => OperationBinaryCommand.new( :"<" ),
|
45
|
+
:"<=" => OperationBinaryCommand.new( :"<=" ),
|
46
|
+
:">" => OperationBinaryCommand.new( :">" ),
|
47
|
+
:">=" => OperationBinaryCommand.new( :">=" ),
|
48
|
+
:"|" => OperationBinaryCommand.new( :"|" ),
|
49
|
+
}
|
50
|
+
def self.get_operation_command( name )
|
51
|
+
if @operation_unary_commands.include? name
|
52
|
+
return @operation_unary_commands[name]
|
53
|
+
else
|
54
|
+
raise "NOT SUPPORTED"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class ContextNodeCommand < AbstractCommand # :nodoc:
|
59
|
+
def initialize(); end
|
60
|
+
def command_type; :context_node end
|
61
|
+
@@instance = self.new()
|
62
|
+
def self.get_instance
|
63
|
+
@@instance
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class RootNodeCommand < AbstractCommand # :nodoc:
|
68
|
+
def initialize(); end
|
69
|
+
def command_type; :root_node end
|
70
|
+
@@instance = self.new()
|
71
|
+
def self.get_instance
|
72
|
+
@@instance
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class NodeSelectionCommand < AbstractCommand # :nodoc:
|
77
|
+
def initialize( axis, node_type, node_ns_uri, node_name, pred_exprs )
|
78
|
+
@axis = axis
|
79
|
+
@node_type = node_type
|
80
|
+
@node_ns_uri = node_ns_uri
|
81
|
+
@node_name = node_name
|
82
|
+
@pred_exprs = pred_exprs
|
83
|
+
end
|
84
|
+
def command_type; :node_selection end
|
85
|
+
attr_reader :axis
|
86
|
+
attr_reader :node_type
|
87
|
+
attr_reader :node_ns_uri
|
88
|
+
attr_reader :node_name
|
89
|
+
attr_reader :pred_exprs
|
90
|
+
end
|
91
|
+
|
92
|
+
class ExprEvalCommand < AbstractCommand # :nodoc:
|
93
|
+
def initialize( expr )
|
94
|
+
@expr = expr
|
95
|
+
end
|
96
|
+
attr_reader :expr
|
97
|
+
def command_type; :expr_eval end
|
98
|
+
end
|
99
|
+
|
100
|
+
class FunctionCallCommand < AbstractCommand # :nodoc:
|
101
|
+
EMPTY_ARGS = Array.new().freeze()
|
102
|
+
def initialize( name, arg_exprs )
|
103
|
+
@function_name = name
|
104
|
+
@function_args = arg_exprs # nil �܂���
|
105
|
+
end
|
106
|
+
attr_reader :function_name
|
107
|
+
def function_args
|
108
|
+
@function_args.nil? ? EMPTY_ARGS : @function_args
|
109
|
+
end
|
110
|
+
def command_type; :function_call end
|
111
|
+
end
|
112
|
+
|
113
|
+
class PredsEvalCommand < AbstractCommand # :nodoc:
|
114
|
+
def initialize( exprs )
|
115
|
+
@exprs = exprs
|
116
|
+
end
|
117
|
+
attr_reader :exprs
|
118
|
+
def command_type; :preds_eval end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
@@ -0,0 +1,307 @@
|
|
1
|
+
# coding : utf-8
|
2
|
+
|
3
|
+
require "vcdom/xpath/internal/value"
|
4
|
+
|
5
|
+
module VCDOM::XPath::Internal # :nodoc:
|
6
|
+
|
7
|
+
class Evaluator # :nodoc:
|
8
|
+
|
9
|
+
def context_node; @context_node_stack[-1] end
|
10
|
+
def context_size; @context_size_stack[-1] end
|
11
|
+
def context_position; @context_pos_stack[-1] end
|
12
|
+
|
13
|
+
def change_context_node_and_position( context_node, position, &block )
|
14
|
+
@context_node_stack.push context_node
|
15
|
+
@context_pos_stack.push position
|
16
|
+
block.call
|
17
|
+
@context_pos_stack.pop
|
18
|
+
@context_node_stack.pop
|
19
|
+
end
|
20
|
+
def change_context_size( size, &block )
|
21
|
+
@context_size_stack.push size
|
22
|
+
block.call
|
23
|
+
@context_size_stack.pop
|
24
|
+
end
|
25
|
+
|
26
|
+
def evaluate_expr( expr )
|
27
|
+
# TODO
|
28
|
+
case expr.expr_type
|
29
|
+
when :or_expr
|
30
|
+
return evaluate_or_expr( expr )
|
31
|
+
when :and_expr
|
32
|
+
return evaluate_and_expr( expr )
|
33
|
+
when :equality_expr
|
34
|
+
return evaluate_equality_expr( expr )
|
35
|
+
else
|
36
|
+
raise "INTERNAL ERROR"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def evaluate_or_expr( expr )
|
41
|
+
# TODO
|
42
|
+
raise "NOT STILL BE SUPPORTED"
|
43
|
+
end
|
44
|
+
|
45
|
+
def evaluate_and_expr( expr )
|
46
|
+
# TODO
|
47
|
+
raise "NOT STILL BE SUPPORTED"
|
48
|
+
end
|
49
|
+
|
50
|
+
def evaluate_equality_expr( expr )
|
51
|
+
# TODO
|
52
|
+
val_stack = Array.new()
|
53
|
+
expr.each do |e|
|
54
|
+
if e.is_value? or e.is_expr? then
|
55
|
+
val_stack.push e
|
56
|
+
else
|
57
|
+
case e.command_type
|
58
|
+
when :operation_unary
|
59
|
+
operand = val_stack.pop
|
60
|
+
val_stack.push operand.send( e.operation_name )
|
61
|
+
when :operation_binary
|
62
|
+
operand2 = val_stack.pop
|
63
|
+
operand1 = val_stack.pop
|
64
|
+
val_stack.push operand1.send( e.operation_name, operand2 )
|
65
|
+
when :expr_eval
|
66
|
+
val_stack.push evaluate_expr( e.expr )
|
67
|
+
when :function_call
|
68
|
+
args = Array.new()
|
69
|
+
e.function_args.each do |arg_expr|
|
70
|
+
args << evaluate_expr( arg_expr )
|
71
|
+
end
|
72
|
+
val_stack.push( call_function( e.function_name, args ) )
|
73
|
+
when :node_selection
|
74
|
+
target = val_stack.pop
|
75
|
+
val_stack.push evaluate_node_selection( target, e )
|
76
|
+
when :preds_eval
|
77
|
+
target = val_stack.pop
|
78
|
+
val_stack.push evaluate_preds( target, e.exprs )
|
79
|
+
when :context_node
|
80
|
+
val_stack.push create_node_set_value( context_node )
|
81
|
+
when :root_node
|
82
|
+
# TODO : context_node.class::DOCUMENT_NODE を書き換え
|
83
|
+
root_node = ( context_node.node_type == context_node.class::DOCUMENT_NODE ? context_node : context_node.owner_document )
|
84
|
+
val_stack.push create_node_set_value( root_node )
|
85
|
+
else
|
86
|
+
raise "NOT SUPPORTED"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
raise "INTERNAL ERROR" if val_stack.length != 1
|
91
|
+
return val_stack.pop
|
92
|
+
end
|
93
|
+
|
94
|
+
def call_function( name, args )
|
95
|
+
args.each do |a|
|
96
|
+
raise "USER ERROR" unless a.is_value?
|
97
|
+
end
|
98
|
+
send( "_xpath_#{name}".intern, *args )
|
99
|
+
end
|
100
|
+
|
101
|
+
NODE_SELECTION_BY_AXIS_PROCS = {
|
102
|
+
:'self' => lambda { |c_node, new_nodes|
|
103
|
+
new_nodes << c_node
|
104
|
+
},
|
105
|
+
:'child' => lambda { |c_node, new_nodes|
|
106
|
+
c_node.each_child_node { |n| new_nodes << n }
|
107
|
+
},
|
108
|
+
:'parent' => lambda { |c_node, new_nodes|
|
109
|
+
if c_node.node_type == c_node.class::ATTRIBUTE_NODE then # TODO
|
110
|
+
new_nodes << c_node.owner_element if c_node.owner_element
|
111
|
+
elsif c_node.node_type == :xpath_namespace_node then
|
112
|
+
raise "NOT SUPPORTED"
|
113
|
+
else
|
114
|
+
new_nodes << c_node.parent_node if c_node.parent_node
|
115
|
+
end
|
116
|
+
},
|
117
|
+
:'descendant' => lambda { |c_node, new_nodes|
|
118
|
+
node = c_node.first_child
|
119
|
+
if node then
|
120
|
+
while not node.equal? c_node do
|
121
|
+
new_nodes << node
|
122
|
+
if node.first_child then
|
123
|
+
node = node.first_child
|
124
|
+
elsif node.next_sibling
|
125
|
+
node = node.next_sibling
|
126
|
+
else
|
127
|
+
# TODO
|
128
|
+
node = node.parent_node
|
129
|
+
while not node.equal? c_node do
|
130
|
+
if node.next_sibling then
|
131
|
+
node = node.next_sibling
|
132
|
+
break
|
133
|
+
else
|
134
|
+
node = node.parent_node
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
},
|
141
|
+
:'descendant-or-self' => lambda { |c_node, new_nodes|
|
142
|
+
new_nodes << c_node
|
143
|
+
NODE_SELECTION_BY_AXIS_PROCS[:"descendant"].call( c_node, new_nodes )
|
144
|
+
},
|
145
|
+
:'ancestor' => lambda { |c_node, new_nodes|
|
146
|
+
node = c_node.parent_node
|
147
|
+
while node do
|
148
|
+
new_nodes << node
|
149
|
+
node = node.parent_node
|
150
|
+
end
|
151
|
+
},
|
152
|
+
:'ancestor-or-self' => lambda { |c_node, new_nodes|
|
153
|
+
new_nodes << c_node
|
154
|
+
NODE_SELECTION_BY_AXIS_PROCS[:"ancestor"].call( c_node, new_nodes )
|
155
|
+
},
|
156
|
+
:'following' => lambda { |c_node, new_nodes|
|
157
|
+
raise "NOT SUPPORTED"
|
158
|
+
},
|
159
|
+
:'following-sibling' => lambda { |c_node, new_nodes|
|
160
|
+
raise "NOT SUPPORTED"
|
161
|
+
},
|
162
|
+
:'preceding' => lambda { |c_node, new_nodes|
|
163
|
+
raise "NOT SUPPORTED"
|
164
|
+
},
|
165
|
+
:'preceding-sibling' => lambda { |c_node, new_nodes|
|
166
|
+
raise "NOT SUPPORTED"
|
167
|
+
},
|
168
|
+
:'attribute' => lambda { |c_node, new_nodes|
|
169
|
+
if c_node.attributes then
|
170
|
+
c_node.attributes.each do |n|
|
171
|
+
if n.namespace_uri != "http://www.w3.org/2000/xmlns/" then
|
172
|
+
new_nodes << n
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
},
|
177
|
+
:'namespace' => lambda { |c_node, new_nodes|
|
178
|
+
raise "NOT SUPPORTED"
|
179
|
+
},
|
180
|
+
}
|
181
|
+
|
182
|
+
def evaluate_node_selection( nodes, cmd )
|
183
|
+
# cmd.pred_exprs は nil の可能性あり
|
184
|
+
# cmd.node_test_name も nil の可能性あり
|
185
|
+
# cmd.node_test_type は :any, :, :processing-instruction など
|
186
|
+
new_nodes = Array.new()
|
187
|
+
nodes.each do |c_node|
|
188
|
+
c_nodes = Array.new()
|
189
|
+
# TODO : 軸によって対象となるノードを集める
|
190
|
+
if ( node_selection_by_axis_proc = NODE_SELECTION_BY_AXIS_PROCS[ cmd.axis ] ).nil? then
|
191
|
+
raise "invalid axis [#{cmd.axis}]"
|
192
|
+
end
|
193
|
+
node_selection_by_axis_proc.call( c_node, c_nodes )
|
194
|
+
# type, name, ns url によって絞り込む
|
195
|
+
c_nodes = evaluate_node_selection_sub( c_nodes, cmd )
|
196
|
+
# TODO : 軸によって順序を変更?
|
197
|
+
if cmd.pred_exprs then
|
198
|
+
cmd.pred_exprs.each do |expr|
|
199
|
+
c_nodes = evaluate_pred_internal( c_nodes, expr )
|
200
|
+
end
|
201
|
+
end
|
202
|
+
new_nodes.concat c_nodes
|
203
|
+
end
|
204
|
+
new_nodes.uniq!
|
205
|
+
create_node_set_value( *new_nodes )
|
206
|
+
end
|
207
|
+
|
208
|
+
def evaluate_node_selection_sub( nodes, cmd )
|
209
|
+
# node_type での絞り込み
|
210
|
+
case cmd.node_type
|
211
|
+
when :node
|
212
|
+
# do nothing
|
213
|
+
when :named_node
|
214
|
+
case cmd.axis
|
215
|
+
when :attribute
|
216
|
+
raise "NOT SUPPORTED"
|
217
|
+
when :namespace
|
218
|
+
raise "NOT SUPPORTED"
|
219
|
+
else
|
220
|
+
expected_type = VCDOM::Node::ELEMENT_NODE # TODO : change
|
221
|
+
end
|
222
|
+
nodes = nodes.inject( Array.new() ) do |arr,n|
|
223
|
+
arr << n if n.node_type == expected_type
|
224
|
+
end
|
225
|
+
else
|
226
|
+
raise "NOT SUPPORTED"
|
227
|
+
end
|
228
|
+
new_nodes = Array.new()
|
229
|
+
# node_ns_url での絞り込み # node_name での絞り込み
|
230
|
+
if cmd.node_ns_uri.nil? then #and cmd.node_name.nil? then
|
231
|
+
if cmd.node_name.nil? then
|
232
|
+
new_nodes = nodes
|
233
|
+
else
|
234
|
+
nodes.each do |n|
|
235
|
+
new_nodes << n if n.namespace_uri.nil? and ( n.local_name || n.node_name ) == cmd.node_name.to_s
|
236
|
+
end
|
237
|
+
end
|
238
|
+
else
|
239
|
+
nodes.each do |n|
|
240
|
+
new_nodes << n if n.namespace_uri == cmd.node_ns_uri.to_s and n.local_name == cmd.node_name.to_s
|
241
|
+
end
|
242
|
+
end
|
243
|
+
new_nodes
|
244
|
+
end
|
245
|
+
|
246
|
+
def evaluate_preds( nodes, exprs )
|
247
|
+
raise "User Error?" if nodes.value_type != :node_set
|
248
|
+
# TODO
|
249
|
+
nodes.sort()
|
250
|
+
nodes = nodes.value
|
251
|
+
exprs.each do |expr|
|
252
|
+
nodes = evaluate_pred_internal( nodes, expr )
|
253
|
+
end
|
254
|
+
create_node_set_value( *nodes )
|
255
|
+
end
|
256
|
+
|
257
|
+
# evaluate_preds および evaluate_node_selection から呼び出される
|
258
|
+
def evaluate_pred_internal( nodes, expr )
|
259
|
+
new_nodes = Array.new()
|
260
|
+
change_context_size( nodes.length ) do
|
261
|
+
nodes.each_with_index do |node,i|
|
262
|
+
change_context_node_and_position( node, i+1 ) do
|
263
|
+
res = evaluate_expr( expr )
|
264
|
+
if ( res.value_type == :number and res.value == context_position ) or
|
265
|
+
( res.value_type != :number and res.to_boolean_value.value ) then
|
266
|
+
new_nodes << node
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
new_nodes
|
272
|
+
end
|
273
|
+
|
274
|
+
def create_number_value( num )
|
275
|
+
NumberValue.new( num.to_f )
|
276
|
+
end
|
277
|
+
def create_boolean_value( bool )
|
278
|
+
bool ? BooleanValue::TRUE : BooleanValue::FALSE
|
279
|
+
end
|
280
|
+
def create_string_value( str )
|
281
|
+
StringValue.new( str )
|
282
|
+
end
|
283
|
+
def create_node_set_value( *nodes )
|
284
|
+
NodeSetValue.new( *nodes )
|
285
|
+
end
|
286
|
+
|
287
|
+
def initialize( context_node )
|
288
|
+
( @context_node_stack = Array.new() ).push context_node
|
289
|
+
( @context_size_stack = Array.new() ).push 1
|
290
|
+
( @context_pos_stack = Array.new() ).push 1
|
291
|
+
end
|
292
|
+
|
293
|
+
def self.set_xpath_function( name, func )
|
294
|
+
define_method "_xpath_#{name}".intern, func
|
295
|
+
end
|
296
|
+
|
297
|
+
end
|
298
|
+
|
299
|
+
# setting xpath functions
|
300
|
+
Evaluator.set_xpath_function( :position, lambda { || create_number_value( context_position ) } )
|
301
|
+
Evaluator.set_xpath_function( :true, lambda { || create_boolean_value( true ) } )
|
302
|
+
Evaluator.set_xpath_function( :false, lambda { || create_boolean_value( false ) } )
|
303
|
+
Evaluator.set_xpath_function( :string, lambda { |*args|
|
304
|
+
raise "ERROR" if args.length > 2
|
305
|
+
( args.length == 0 ? NodeSetValue.new( context_node ) : args[0] ).to_string_value } )
|
306
|
+
|
307
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding : utf-8
|
2
|
+
|
3
|
+
module VCDOM::XPath::Internal # :nodoc:
|
4
|
+
|
5
|
+
class AbstractExpr < Array # :nodoc:
|
6
|
+
def initialize( *expr_elems )
|
7
|
+
expr_elems.each do |e|
|
8
|
+
self << e
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def is_value?; false end
|
13
|
+
def is_expr?; true end
|
14
|
+
def is_command?; false end
|
15
|
+
end
|
16
|
+
|
17
|
+
class OrExpr < AbstractExpr # :nodoc:
|
18
|
+
def expr_type
|
19
|
+
:or_expr
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class AndExpr < AbstractExpr # :nodoc:
|
24
|
+
def expr_type
|
25
|
+
:and_expr
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class EqualityExpr < AbstractExpr # :nodoc:
|
30
|
+
def expr_type
|
31
|
+
:equality_expr
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|