oga 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +57 -0
- data/doc/changelog.md +128 -0
- data/doc/css/common.css +5 -4
- data/doc/css_selectors.md +935 -0
- data/doc/manually_creating_documents.md +67 -0
- data/doc/xml_namespaces.md +63 -0
- data/ext/c/lexer.c +745 -628
- data/ext/c/lexer.h +8 -0
- data/ext/c/lexer.rl +44 -7
- data/ext/java/org/liboga/xml/Lexer.java +351 -232
- data/ext/java/org/liboga/xml/Lexer.rl +29 -8
- data/ext/ragel/base_lexer.rl +68 -18
- data/lib/oga.rb +4 -1
- data/lib/oga/css/lexer.rb +743 -0
- data/lib/oga/css/parser.rb +828 -0
- data/lib/oga/version.rb +1 -1
- data/lib/oga/xml/attribute.rb +3 -1
- data/lib/oga/xml/element.rb +15 -1
- data/lib/oga/xml/entities.rb +60 -0
- data/lib/oga/xml/html_void_elements.rb +2 -0
- data/lib/oga/xml/lexer.rb +36 -28
- data/lib/oga/xml/node_set.rb +22 -0
- data/lib/oga/xml/parser.rb +149 -128
- data/lib/oga/xml/querying.rb +24 -0
- data/lib/oga/xml/sax_parser.rb +55 -1
- data/lib/oga/xml/text.rb +6 -1
- data/lib/oga/xpath/evaluator.rb +138 -101
- data/lib/oga/xpath/lexer.rb +1205 -1294
- data/lib/oga/xpath/parser.rb +228 -204
- metadata +9 -4
- data/lib/oga/xpath/node.rb +0 -10
data/lib/oga/xml/querying.rb
CHANGED
@@ -27,6 +27,30 @@ module Oga
|
|
27
27
|
|
28
28
|
return result.is_a?(XML::NodeSet) ? result.first : result
|
29
29
|
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Evaluates the given CSS expression.
|
33
|
+
#
|
34
|
+
# @param [String] expression The CSS expression to run.
|
35
|
+
# @see [Oga::XPath::Evaluator#initialize]
|
36
|
+
#
|
37
|
+
def css(expression)
|
38
|
+
ast = CSS::Parser.new(expression).parse
|
39
|
+
|
40
|
+
return XPath::Evaluator.new(self).evaluate_ast(ast)
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Evaluates the given CSS expression and returns the first node in the
|
45
|
+
# set.
|
46
|
+
#
|
47
|
+
# @see [#css]
|
48
|
+
#
|
49
|
+
def at_css(*args)
|
50
|
+
result = css(*args)
|
51
|
+
|
52
|
+
return result.is_a?(XML::NodeSet) ? result.first : result
|
53
|
+
end
|
30
54
|
end # Querying
|
31
55
|
end # XML
|
32
56
|
end # Oga
|
data/lib/oga/xml/sax_parser.rb
CHANGED
@@ -37,6 +37,26 @@ module Oga
|
|
37
37
|
# For information on the callback arguments see the documentation of the
|
38
38
|
# corresponding methods in {Oga::XML::Parser}.
|
39
39
|
#
|
40
|
+
# ## Element Callbacks
|
41
|
+
#
|
42
|
+
# The SAX parser changes the behaviour of both `on_element` and
|
43
|
+
# `after_element`. The latter in the regular parser only takes a
|
44
|
+
# {Oga::XML::Element} instance. In the SAX parser it will instead take a
|
45
|
+
# namespace name and the element name. This eases the process of figuring
|
46
|
+
# out what element a callback is associated with.
|
47
|
+
#
|
48
|
+
# An example:
|
49
|
+
#
|
50
|
+
# class SaxHandler
|
51
|
+
# def on_element(namespace, name, attrs = {})
|
52
|
+
# # ...
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# def after_element(namespace, name)
|
56
|
+
# puts name # => "foo", "bar", etc
|
57
|
+
# end
|
58
|
+
# end
|
59
|
+
#
|
40
60
|
class SaxParser < Parser
|
41
61
|
##
|
42
62
|
# @param [Object] handler The SAX handler to delegate callbacks to.
|
@@ -52,12 +72,46 @@ module Oga
|
|
52
72
|
instance_methods.grep(/^(on_|after_)/).each do |method|
|
53
73
|
eval <<-EOF, nil, __FILE__, __LINE__ + 1
|
54
74
|
def #{method}(*args)
|
55
|
-
|
75
|
+
run_callback(:#{method}, *args)
|
56
76
|
|
57
77
|
return
|
58
78
|
end
|
59
79
|
EOF
|
60
80
|
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Manually overwrite `on_element` so we can ensure that `after_element`
|
84
|
+
# always receives the namespace and name.
|
85
|
+
#
|
86
|
+
# @see [Oga::XML::Parser#on_element]
|
87
|
+
# @return [Array]
|
88
|
+
#
|
89
|
+
def on_element(namespace, name, attrs = {})
|
90
|
+
run_callback(:on_element, namespace, name, attrs)
|
91
|
+
|
92
|
+
return namespace, name
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Manually overwrite `after_element` so it can take a namespace and name.
|
97
|
+
# This differs a bit from the regular `after_element` which only takes an
|
98
|
+
# {Oga::XML::Element} instance.
|
99
|
+
#
|
100
|
+
# @param [Array] namespace_with_name
|
101
|
+
#
|
102
|
+
def after_element(namespace_with_name)
|
103
|
+
run_callback(:after_element, *namespace_with_name)
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
##
|
109
|
+
# @param [Symbol] method
|
110
|
+
# @param [Array] args
|
111
|
+
#
|
112
|
+
def run_callback(method, *args)
|
113
|
+
@handler.send(method, *args) if @handler.respond_to?(method)
|
114
|
+
end
|
61
115
|
end # SaxParser
|
62
116
|
end # XML
|
63
117
|
end # Oga
|
data/lib/oga/xml/text.rb
CHANGED
data/lib/oga/xpath/evaluator.rb
CHANGED
@@ -2,7 +2,7 @@ module Oga
|
|
2
2
|
module XPath
|
3
3
|
##
|
4
4
|
# The Evaluator class evaluates XPath expressions, either as a String or an
|
5
|
-
# AST of
|
5
|
+
# AST of `AST::Node` instances.
|
6
6
|
#
|
7
7
|
# ## Thread Safety
|
8
8
|
#
|
@@ -90,7 +90,7 @@ module Oga
|
|
90
90
|
##
|
91
91
|
# Evaluates a pre-parsed XPath expression.
|
92
92
|
#
|
93
|
-
# @param [
|
93
|
+
# @param [AST::Node] ast
|
94
94
|
# @return [Mixed]
|
95
95
|
#
|
96
96
|
def evaluate_ast(ast)
|
@@ -104,7 +104,7 @@ module Oga
|
|
104
104
|
# dedicated handler method. Handler methods are called "on_X" where "X" is
|
105
105
|
# the node type.
|
106
106
|
#
|
107
|
-
# @param [
|
107
|
+
# @param [AST::Node] ast_node The XPath AST node to process.
|
108
108
|
#
|
109
109
|
# @param [Oga::XML::NodeSet] context The context (a set of nodes) to
|
110
110
|
# evaluate an expression in.
|
@@ -120,7 +120,7 @@ module Oga
|
|
120
120
|
##
|
121
121
|
# Processes an absolute XPath expression such as `/foo`.
|
122
122
|
#
|
123
|
-
# @param [
|
123
|
+
# @param [AST::Node] ast_node
|
124
124
|
# @param [Oga::XML::NodeSet] context
|
125
125
|
# @return [Oga::XML::NodeSet]
|
126
126
|
#
|
@@ -142,7 +142,7 @@ module Oga
|
|
142
142
|
# `&&` / `and` operator. Whenever a path results in an empty node set the
|
143
143
|
# evaluation is aborted immediately.
|
144
144
|
#
|
145
|
-
# @param [
|
145
|
+
# @param [AST::Node] ast_node
|
146
146
|
# @param [Oga::XML::NodeSet] context
|
147
147
|
# @return [Oga::XML::NodeSet]
|
148
148
|
#
|
@@ -163,28 +163,45 @@ module Oga
|
|
163
163
|
end
|
164
164
|
|
165
165
|
##
|
166
|
-
# Processes a node test
|
166
|
+
# Processes a node test.
|
167
167
|
#
|
168
|
-
# @param [
|
168
|
+
# @param [AST::Node] ast_node
|
169
169
|
# @param [Oga::XML::NodeSet] context
|
170
170
|
# @return [Oga::XML::NodeSet]
|
171
171
|
#
|
172
172
|
def on_test(ast_node, context)
|
173
|
-
nodes
|
174
|
-
predicate = ast_node.children[2]
|
175
|
-
xpath_index = 1
|
173
|
+
nodes = XML::NodeSet.new
|
176
174
|
|
177
175
|
context.each do |xml_node|
|
178
|
-
|
176
|
+
nodes << xml_node if node_matches?(xml_node, ast_node)
|
177
|
+
end
|
178
|
+
|
179
|
+
return nodes
|
180
|
+
end
|
181
|
+
|
182
|
+
##
|
183
|
+
# Processes a predicate.
|
184
|
+
#
|
185
|
+
# @param [AST::Node] ast_node
|
186
|
+
# @param [Oga::XML::NodeSet] context
|
187
|
+
# @return [Oga::XML::NodeSet]
|
188
|
+
#
|
189
|
+
def on_predicate(ast_node, context)
|
190
|
+
test, predicate = *ast_node
|
191
|
+
final_nodes = XML::NodeSet.new
|
192
|
+
|
193
|
+
context.each do |context_node|
|
194
|
+
initial_nodes = process(test, XML::NodeSet.new([context_node]))
|
195
|
+
xpath_index = 1
|
179
196
|
|
180
|
-
|
181
|
-
retval = with_node_set(
|
197
|
+
initial_nodes.each do |xml_node|
|
198
|
+
retval = with_node_set(initial_nodes) do
|
182
199
|
process(predicate, XML::NodeSet.new([xml_node]))
|
183
200
|
end
|
184
201
|
|
185
202
|
# Numeric values are used as node set indexes.
|
186
203
|
if retval.is_a?(Numeric)
|
187
|
-
|
204
|
+
final_nodes << xml_node if retval.to_i == xpath_index
|
188
205
|
|
189
206
|
# Node sets, strings, booleans, etc
|
190
207
|
elsif retval
|
@@ -192,16 +209,14 @@ module Oga
|
|
192
209
|
next
|
193
210
|
end
|
194
211
|
|
195
|
-
|
212
|
+
final_nodes << xml_node
|
196
213
|
end
|
197
|
-
else
|
198
|
-
nodes << xml_node
|
199
|
-
end
|
200
214
|
|
201
|
-
|
215
|
+
xpath_index += 1
|
216
|
+
end
|
202
217
|
end
|
203
218
|
|
204
|
-
return
|
219
|
+
return final_nodes
|
205
220
|
end
|
206
221
|
|
207
222
|
##
|
@@ -209,7 +224,7 @@ module Oga
|
|
209
224
|
# similar to {#process} except the handler names are "on_axis_X" with "X"
|
210
225
|
# being the axis name.
|
211
226
|
#
|
212
|
-
# @param [
|
227
|
+
# @param [AST::Node] ast_node
|
213
228
|
# @param [Oga::XML::NodeSet] context
|
214
229
|
# @return [Oga::XML::NodeSet]
|
215
230
|
#
|
@@ -228,7 +243,7 @@ module Oga
|
|
228
243
|
# Evaluation happens using a "short-circuit" mechanism. The moment a
|
229
244
|
# matching node is found it is returned immediately.
|
230
245
|
#
|
231
|
-
# @param [
|
246
|
+
# @param [AST::Node] ast_node
|
232
247
|
# @param [Oga::XML::NodeSet] context
|
233
248
|
# @return [Oga::XML::NodeSet]
|
234
249
|
#
|
@@ -279,7 +294,7 @@ module Oga
|
|
279
294
|
# (unlike some other methods which return the moment they find a matching
|
280
295
|
# node).
|
281
296
|
#
|
282
|
-
# @param [
|
297
|
+
# @param [AST::Node] ast_node
|
283
298
|
# @param [Oga::XML::NodeSet] context
|
284
299
|
# @return [Oga::XML::NodeSet]
|
285
300
|
#
|
@@ -299,7 +314,7 @@ module Oga
|
|
299
314
|
# Evaluates the `child` axis. This axis simply takes all the child nodes
|
300
315
|
# of the current context nodes.
|
301
316
|
#
|
302
|
-
# @param [
|
317
|
+
# @param [AST::Node] ast_node
|
303
318
|
# @param [Oga::XML::NodeSet] context
|
304
319
|
# @return [Oga::XML::NodeSet]
|
305
320
|
#
|
@@ -311,7 +326,7 @@ module Oga
|
|
311
326
|
# Evaluates the `descendant` axis. This method processes child nodes until
|
312
327
|
# the very end of the tree, no "short-circuiting" mechanism is used.
|
313
328
|
#
|
314
|
-
# @param [
|
329
|
+
# @param [AST::Node] ast_node
|
315
330
|
# @param [Oga::XML::NodeSet] context
|
316
331
|
# @return [Oga::XML::NodeSet]
|
317
332
|
#
|
@@ -319,12 +334,8 @@ module Oga
|
|
319
334
|
nodes = XML::NodeSet.new
|
320
335
|
|
321
336
|
context.each do |context_node|
|
322
|
-
context_node.children.each do |node|
|
323
|
-
nodes << node if node_matches?(node, ast_node)
|
324
|
-
end
|
325
|
-
|
326
337
|
context_node.each_node do |node|
|
327
|
-
nodes
|
338
|
+
nodes.concat(process(ast_node, XML::NodeSet.new([node])))
|
328
339
|
end
|
329
340
|
end
|
330
341
|
|
@@ -334,7 +345,7 @@ module Oga
|
|
334
345
|
##
|
335
346
|
# Evaluates the `descendant-or-self` axis.
|
336
347
|
#
|
337
|
-
# @param [
|
348
|
+
# @param [AST::Node] ast_node
|
338
349
|
# @param [Oga::XML::NodeSet] context
|
339
350
|
# @return [Oga::XML::NodeSet]
|
340
351
|
#
|
@@ -349,17 +360,18 @@ module Oga
|
|
349
360
|
##
|
350
361
|
# Evaluates the `following` axis.
|
351
362
|
#
|
352
|
-
# @param [
|
363
|
+
# @param [AST::Node] ast_node
|
353
364
|
# @param [Oga::XML::NodeSet] context
|
354
365
|
# @return [Oga::XML::NodeSet]
|
355
366
|
#
|
356
367
|
def on_axis_following(ast_node, context)
|
357
368
|
nodes = XML::NodeSet.new
|
369
|
+
root = root_node(@document)
|
358
370
|
|
359
371
|
context.each do |context_node|
|
360
372
|
check = false
|
361
373
|
|
362
|
-
|
374
|
+
root.each_node do |doc_node|
|
363
375
|
# Skip child nodes of the current context node, compare all
|
364
376
|
# following nodes.
|
365
377
|
if doc_node == context_node
|
@@ -379,18 +391,19 @@ module Oga
|
|
379
391
|
##
|
380
392
|
# Evaluates the `following-sibling` axis.
|
381
393
|
#
|
382
|
-
# @param [
|
394
|
+
# @param [AST::Node] ast_node
|
383
395
|
# @param [Oga::XML::NodeSet] context
|
384
396
|
# @return [Oga::XML::NodeSet]
|
385
397
|
#
|
386
398
|
def on_axis_following_sibling(ast_node, context)
|
387
399
|
nodes = XML::NodeSet.new
|
400
|
+
root = parent_node(@document)
|
388
401
|
|
389
402
|
context.each do |context_node|
|
390
403
|
check = false
|
391
404
|
parent = has_parent?(context_node) ? context_node.parent : nil
|
392
405
|
|
393
|
-
|
406
|
+
root.each_node do |doc_node|
|
394
407
|
# Skip child nodes of the current context node, compare all
|
395
408
|
# following nodes.
|
396
409
|
if doc_node == context_node
|
@@ -416,7 +429,7 @@ module Oga
|
|
416
429
|
##
|
417
430
|
# Evaluates the `parent` axis.
|
418
431
|
#
|
419
|
-
# @param [
|
432
|
+
# @param [AST::Node] ast_node
|
420
433
|
# @param [Oga::XML::NodeSet] context
|
421
434
|
# @return [Oga::XML::NodeSet]
|
422
435
|
#
|
@@ -437,17 +450,18 @@ module Oga
|
|
437
450
|
##
|
438
451
|
# Evaluates the `preceding` axis.
|
439
452
|
#
|
440
|
-
# @param [
|
453
|
+
# @param [AST::Node] ast_node
|
441
454
|
# @param [Oga::XML::NodeSet] context
|
442
455
|
# @return [Oga::XML::NodeSet]
|
443
456
|
#
|
444
457
|
def on_axis_preceding(ast_node, context)
|
445
458
|
nodes = XML::NodeSet.new
|
459
|
+
root = root_node(@document)
|
446
460
|
|
447
461
|
context.each do |context_node|
|
448
462
|
check = true
|
449
463
|
|
450
|
-
|
464
|
+
root.each_node do |doc_node|
|
451
465
|
# Test everything *until* we hit the current context node.
|
452
466
|
if doc_node == context_node
|
453
467
|
break
|
@@ -463,18 +477,19 @@ module Oga
|
|
463
477
|
##
|
464
478
|
# Evaluates the `preceding-sibling` axis.
|
465
479
|
#
|
466
|
-
# @param [
|
480
|
+
# @param [AST::Node] ast_node
|
467
481
|
# @param [Oga::XML::NodeSet] context
|
468
482
|
# @return [Oga::XML::NodeSet]
|
469
483
|
#
|
470
484
|
def on_axis_preceding_sibling(ast_node, context)
|
471
485
|
nodes = XML::NodeSet.new
|
486
|
+
root = parent_node(@document)
|
472
487
|
|
473
488
|
context.each do |context_node|
|
474
489
|
check = true
|
475
490
|
parent = has_parent?(context_node) ? context_node.parent : nil
|
476
491
|
|
477
|
-
|
492
|
+
root.each_node do |doc_node|
|
478
493
|
# Test everything *until* we hit the current context node.
|
479
494
|
if doc_node == context_node
|
480
495
|
break
|
@@ -490,7 +505,7 @@ module Oga
|
|
490
505
|
##
|
491
506
|
# Evaluates the `self` axis.
|
492
507
|
#
|
493
|
-
# @param [
|
508
|
+
# @param [AST::Node] ast_node
|
494
509
|
# @param [Oga::XML::NodeSet] context
|
495
510
|
# @return [Oga::XML::NodeSet]
|
496
511
|
#
|
@@ -507,7 +522,7 @@ module Oga
|
|
507
522
|
##
|
508
523
|
# Evaluates the `namespace` axis.
|
509
524
|
#
|
510
|
-
# @param [
|
525
|
+
# @param [AST::Node] ast_node
|
511
526
|
# @param [Oga::XML::NodeSet] context
|
512
527
|
# @return [Oga::XML::NodeSet]
|
513
528
|
#
|
@@ -531,7 +546,7 @@ module Oga
|
|
531
546
|
##
|
532
547
|
# Dispatches node type matching to dedicated handlers.
|
533
548
|
#
|
534
|
-
# @param [
|
549
|
+
# @param [AST::Node] ast_node
|
535
550
|
# @param [Oga::XML::NodeSet] context
|
536
551
|
# @return [Oga::XML::NodeSet]
|
537
552
|
#
|
@@ -546,7 +561,7 @@ module Oga
|
|
546
561
|
##
|
547
562
|
# Processes the `node` type matcher. This matcher matches all node types.
|
548
563
|
#
|
549
|
-
# @param [
|
564
|
+
# @param [AST::Node] ast_node
|
550
565
|
# @param [Oga::XML::NodeSet] context
|
551
566
|
# @return [Oga::XML::NodeSet]
|
552
567
|
#
|
@@ -554,7 +569,9 @@ module Oga
|
|
554
569
|
nodes = XML::NodeSet.new
|
555
570
|
|
556
571
|
context.each do |node|
|
557
|
-
|
572
|
+
if node.is_a?(XML::Node) or node.is_a?(XML::Document)
|
573
|
+
nodes << node
|
574
|
+
end
|
558
575
|
end
|
559
576
|
|
560
577
|
return nodes
|
@@ -563,7 +580,7 @@ module Oga
|
|
563
580
|
##
|
564
581
|
# Processes the `text()` type test. This matches only text nodes.
|
565
582
|
#
|
566
|
-
# @param [
|
583
|
+
# @param [AST::Node] ast_node
|
567
584
|
# @param [Oga::XML::NodeSet] context
|
568
585
|
# @return [Oga::XML::NodeSet]
|
569
586
|
#
|
@@ -580,7 +597,7 @@ module Oga
|
|
580
597
|
##
|
581
598
|
# Processes the `comment()` type test. This matches only comment nodes.
|
582
599
|
#
|
583
|
-
# @param [
|
600
|
+
# @param [AST::Node] ast_node
|
584
601
|
# @param [Oga::XML::NodeSet] context
|
585
602
|
# @return [Oga::XML::NodeSet]
|
586
603
|
#
|
@@ -598,7 +615,7 @@ module Oga
|
|
598
615
|
# Processes the `processing-instruction()` type test. This matches only
|
599
616
|
# processing-instruction nodes.
|
600
617
|
#
|
601
|
-
# @param [
|
618
|
+
# @param [AST::Node] ast_node
|
602
619
|
# @param [Oga::XML::NodeSet] context
|
603
620
|
# @return [Oga::XML::NodeSet]
|
604
621
|
#
|
@@ -616,7 +633,7 @@ module Oga
|
|
616
633
|
# Processes the pipe (`|`) operator. This operator creates a union of two
|
617
634
|
# sets.
|
618
635
|
#
|
619
|
-
# @param [
|
636
|
+
# @param [AST::Node] ast_node
|
620
637
|
# @param [Oga::XML::NodeSet] context
|
621
638
|
# @return [Oga::XML::NodeSet]
|
622
639
|
#
|
@@ -633,7 +650,7 @@ module Oga
|
|
633
650
|
# evaluate to `true`. If the first expression evaluates to `false` the
|
634
651
|
# right expression is ignored.
|
635
652
|
#
|
636
|
-
# @param [
|
653
|
+
# @param [AST::Node] ast_node
|
637
654
|
# @param [Oga::XML::NodeSet] context
|
638
655
|
# @return [TrueClass|FalseClass]
|
639
656
|
#
|
@@ -650,7 +667,7 @@ module Oga
|
|
650
667
|
# true, otherwise false is returned. If the first expression evaluates to
|
651
668
|
# `true` the second expression is ignored.
|
652
669
|
#
|
653
|
-
# @param [
|
670
|
+
# @param [AST::Node] ast_node
|
654
671
|
# @param [Oga::XML::NodeSet] context
|
655
672
|
# @return [TrueClass|FalseClass]
|
656
673
|
#
|
@@ -666,7 +683,7 @@ module Oga
|
|
666
683
|
# This operator converts the left and right expressions to numbers and
|
667
684
|
# adds them together.
|
668
685
|
#
|
669
|
-
# @param [
|
686
|
+
# @param [AST::Node] ast_node
|
670
687
|
# @param [Oga::XML::NodeSet] context
|
671
688
|
# @return [Float]
|
672
689
|
#
|
@@ -682,7 +699,7 @@ module Oga
|
|
682
699
|
# This operator converts the left and right expressions to numbers and
|
683
700
|
# divides the left number with the right number.
|
684
701
|
#
|
685
|
-
# @param [
|
702
|
+
# @param [AST::Node] ast_node
|
686
703
|
# @param [Oga::XML::NodeSet] context
|
687
704
|
# @return [Float]
|
688
705
|
#
|
@@ -698,7 +715,7 @@ module Oga
|
|
698
715
|
# This operator converts the left and right expressions to numbers and
|
699
716
|
# returns the modulo of the two numbers.
|
700
717
|
#
|
701
|
-
# @param [
|
718
|
+
# @param [AST::Node] ast_node
|
702
719
|
# @param [Oga::XML::NodeSet] context
|
703
720
|
# @return [Float]
|
704
721
|
#
|
@@ -714,7 +731,7 @@ module Oga
|
|
714
731
|
# This operator converts the left and right expressions to numbers and
|
715
732
|
# multiplies the left number with the right number.
|
716
733
|
#
|
717
|
-
# @param [
|
734
|
+
# @param [AST::Node] ast_node
|
718
735
|
# @param [Oga::XML::NodeSet] context
|
719
736
|
# @return [Float]
|
720
737
|
#
|
@@ -730,7 +747,7 @@ module Oga
|
|
730
747
|
# This operator converts the left and right expressions to numbers and
|
731
748
|
# subtracts the right number of the left number.
|
732
749
|
#
|
733
|
-
# @param [
|
750
|
+
# @param [AST::Node] ast_node
|
734
751
|
# @param [Oga::XML::NodeSet] context
|
735
752
|
# @return [Float]
|
736
753
|
#
|
@@ -749,7 +766,7 @@ module Oga
|
|
749
766
|
# compared instead of the nodes themselves. That is, nodes with different
|
750
767
|
# names but the same text are considered to be equal.
|
751
768
|
#
|
752
|
-
# @param [
|
769
|
+
# @param [AST::Node] ast_node
|
753
770
|
# @param [Oga::XML::NodeSet] context
|
754
771
|
# @return [TrueClass|FalseClass]
|
755
772
|
#
|
@@ -863,7 +880,7 @@ module Oga
|
|
863
880
|
# 2. A variable list of XPath function arguments, passed as individual
|
864
881
|
# Ruby method arguments.
|
865
882
|
#
|
866
|
-
# @param [
|
883
|
+
# @param [AST::Node] ast_node
|
867
884
|
# @param [Oga::XML::NodeSet] context
|
868
885
|
# @return [Oga::XML::NodeSet]
|
869
886
|
#
|
@@ -905,7 +922,7 @@ module Oga
|
|
905
922
|
# of nodes in `expression` and returns the result as a float.
|
906
923
|
#
|
907
924
|
# @param [Oga::XML::NodeSet] context
|
908
|
-
# @param [
|
925
|
+
# @param [AST::Node] expression
|
909
926
|
# @return [Float]
|
910
927
|
#
|
911
928
|
def on_call_count(context, expression)
|
@@ -933,7 +950,7 @@ module Oga
|
|
933
950
|
# regardless of the current position.
|
934
951
|
#
|
935
952
|
# @param [Oga::XML::NodeSet] context
|
936
|
-
# @param [
|
953
|
+
# @param [AST::Node] expression
|
937
954
|
# @return [Oga::XML::NodeSet]
|
938
955
|
#
|
939
956
|
def on_call_id(context, expression)
|
@@ -967,7 +984,7 @@ module Oga
|
|
967
984
|
# * The first node in the supplied node set
|
968
985
|
#
|
969
986
|
# @param [Oga::XML::NodeSet] context
|
970
|
-
# @param [
|
987
|
+
# @param [AST::Node] expression
|
971
988
|
# @return [Oga::XML::NodeSet]
|
972
989
|
#
|
973
990
|
def on_call_local_name(context, expression = nil)
|
@@ -984,7 +1001,7 @@ module Oga
|
|
984
1001
|
# present.
|
985
1002
|
#
|
986
1003
|
# @param [Oga::XML::NodeSet] context
|
987
|
-
# @param [
|
1004
|
+
# @param [AST::Node] expression
|
988
1005
|
# @return [Oga::XML::NodeSet]
|
989
1006
|
#
|
990
1007
|
def on_call_name(context, expression = nil)
|
@@ -1010,7 +1027,7 @@ module Oga
|
|
1010
1027
|
# * The first node in the supplied node set
|
1011
1028
|
#
|
1012
1029
|
# @param [Oga::XML::NodeSet] context
|
1013
|
-
# @param [
|
1030
|
+
# @param [AST::Node] expression
|
1014
1031
|
# @return [Oga::XML::NodeSet]
|
1015
1032
|
#
|
1016
1033
|
def on_call_namespace_uri(context, expression = nil)
|
@@ -1034,7 +1051,7 @@ module Oga
|
|
1034
1051
|
# string(10) # => "10"
|
1035
1052
|
#
|
1036
1053
|
# @param [Oga::XML::NodeSet] context
|
1037
|
-
# @param [
|
1054
|
+
# @param [AST::Node] expression
|
1038
1055
|
# @return [String]
|
1039
1056
|
#
|
1040
1057
|
def on_call_string(context, expression = nil)
|
@@ -1066,7 +1083,7 @@ module Oga
|
|
1066
1083
|
#
|
1067
1084
|
# @see [#on_call_string]
|
1068
1085
|
# @param [Oga::XML::NodeSet] context
|
1069
|
-
# @param [
|
1086
|
+
# @param [AST::Node] expression
|
1070
1087
|
# @return [Float]
|
1071
1088
|
#
|
1072
1089
|
def on_call_number(context, expression = nil)
|
@@ -1101,9 +1118,9 @@ module Oga
|
|
1101
1118
|
# them. In case of node sets the text of the set is used.
|
1102
1119
|
#
|
1103
1120
|
# @param [Oga::XML::NodeSet] context
|
1104
|
-
# @param [
|
1105
|
-
# @param [
|
1106
|
-
# @param [Array<
|
1121
|
+
# @param [AST::Node] first
|
1122
|
+
# @param [AST::Node] second
|
1123
|
+
# @param [Array<AST::Node>] rest
|
1107
1124
|
#
|
1108
1125
|
def on_call_concat(context, first, second, *rest)
|
1109
1126
|
args = [first, second] + rest
|
@@ -1126,8 +1143,8 @@ module Oga
|
|
1126
1143
|
# starts-with("hello world", "hello") # => true
|
1127
1144
|
#
|
1128
1145
|
# @param [Oga::XML::NodeSet] context
|
1129
|
-
# @param [
|
1130
|
-
# @param [
|
1146
|
+
# @param [AST::Node] haystack The string to search.
|
1147
|
+
# @param [AST::Node] needle The string to search for.
|
1131
1148
|
# @return [TrueClass|FalseClass]
|
1132
1149
|
#
|
1133
1150
|
def on_call_starts_with(context, haystack, needle)
|
@@ -1148,8 +1165,8 @@ module Oga
|
|
1148
1165
|
# contains("hello world", "o w") # => true
|
1149
1166
|
#
|
1150
1167
|
# @param [Oga::XML::NodeSet] context
|
1151
|
-
# @param [
|
1152
|
-
# @param [
|
1168
|
+
# @param [AST::Node] haystack The string to search.
|
1169
|
+
# @param [AST::Node] needle The string to search for.
|
1153
1170
|
# @return [String]
|
1154
1171
|
#
|
1155
1172
|
def on_call_contains(context, haystack, needle)
|
@@ -1170,8 +1187,8 @@ module Oga
|
|
1170
1187
|
# This would return "2014" as it occurs before the first "-".
|
1171
1188
|
#
|
1172
1189
|
# @param [Oga::XML::NodeSet] context
|
1173
|
-
# @param [
|
1174
|
-
# @param [
|
1190
|
+
# @param [AST::Node] haystack The string to search.
|
1191
|
+
# @param [AST::Node] needle The string to search for.
|
1175
1192
|
# @return [String]
|
1176
1193
|
#
|
1177
1194
|
def on_call_substring_before(context, haystack, needle)
|
@@ -1194,8 +1211,8 @@ module Oga
|
|
1194
1211
|
# This would return "08-25" as it occurs after the first "-".
|
1195
1212
|
#
|
1196
1213
|
# @param [Oga::XML::NodeSet] context
|
1197
|
-
# @param [
|
1198
|
-
# @param [
|
1214
|
+
# @param [AST::Node] haystack The string to search.
|
1215
|
+
# @param [AST::Node] needle The string to search for.
|
1199
1216
|
# @return [String]
|
1200
1217
|
#
|
1201
1218
|
def on_call_substring_after(context, haystack, needle)
|
@@ -1227,9 +1244,9 @@ module Oga
|
|
1227
1244
|
# substring(users/user/username, 5)
|
1228
1245
|
#
|
1229
1246
|
# @param [Oga::XML::NodeSet] context
|
1230
|
-
# @param [
|
1231
|
-
# @param [
|
1232
|
-
# @param [
|
1247
|
+
# @param [AST::Node] haystack
|
1248
|
+
# @param [AST::Node] start
|
1249
|
+
# @param [AST::Node] length
|
1233
1250
|
# @return [String]
|
1234
1251
|
#
|
1235
1252
|
def on_call_substring(context, haystack, start, length = nil)
|
@@ -1255,7 +1272,7 @@ module Oga
|
|
1255
1272
|
#
|
1256
1273
|
# @see [#on_call_string]
|
1257
1274
|
# @param [Oga::XML::NodeSet] context
|
1258
|
-
# @param [
|
1275
|
+
# @param [AST::Node] expression
|
1259
1276
|
# @return [Float]
|
1260
1277
|
#
|
1261
1278
|
def on_call_string_length(context, expression = nil)
|
@@ -1273,7 +1290,7 @@ module Oga
|
|
1273
1290
|
# normalize-space(" fo o ") # => "fo o"
|
1274
1291
|
#
|
1275
1292
|
# @param [Oga::XML::NodeSet] context
|
1276
|
-
# @param [
|
1293
|
+
# @param [AST::Node] expression
|
1277
1294
|
# @return [String]
|
1278
1295
|
#
|
1279
1296
|
def on_call_normalize_space(context, expression = nil)
|
@@ -1292,9 +1309,9 @@ module Oga
|
|
1292
1309
|
# translate("bar", "abc", "ABC") # => "BAr"
|
1293
1310
|
#
|
1294
1311
|
# @param [Oga::XML::NodeSet] context
|
1295
|
-
# @param [
|
1296
|
-
# @param [
|
1297
|
-
# @param [
|
1312
|
+
# @param [AST::Node] input
|
1313
|
+
# @param [AST::Node] find
|
1314
|
+
# @param [AST::Node] replace
|
1298
1315
|
# @return [String]
|
1299
1316
|
#
|
1300
1317
|
def on_call_translate(context, input, find, replace)
|
@@ -1325,7 +1342,7 @@ module Oga
|
|
1325
1342
|
# The boolean `false` is returned for all other cases.
|
1326
1343
|
#
|
1327
1344
|
# @param [Oga::XML::NodeSet] context
|
1328
|
-
# @param [
|
1345
|
+
# @param [AST::Node] expression
|
1329
1346
|
# @return [TrueClass|FalseClass]
|
1330
1347
|
#
|
1331
1348
|
def on_call_boolean(context, expression)
|
@@ -1349,7 +1366,7 @@ module Oga
|
|
1349
1366
|
# `true` then this function returns `false` instead.
|
1350
1367
|
#
|
1351
1368
|
# @param [Oga::XML::NodeSet] context
|
1352
|
-
# @param [
|
1369
|
+
# @param [AST::Node] expression
|
1353
1370
|
# @return [TrueClass|FalseClass]
|
1354
1371
|
#
|
1355
1372
|
def on_call_not(context, expression)
|
@@ -1361,7 +1378,7 @@ module Oga
|
|
1361
1378
|
#
|
1362
1379
|
# This function simply returns the boolean `true`.
|
1363
1380
|
#
|
1364
|
-
# @param [
|
1381
|
+
# @param [AST::NodeSet] context
|
1365
1382
|
# @return [TrueClass]
|
1366
1383
|
#
|
1367
1384
|
def on_call_true(context)
|
@@ -1373,7 +1390,7 @@ module Oga
|
|
1373
1390
|
#
|
1374
1391
|
# This function simply returns the boolean `false`.
|
1375
1392
|
#
|
1376
|
-
# @param [
|
1393
|
+
# @param [AST::NodeSet] context
|
1377
1394
|
# @return [FalseClass]
|
1378
1395
|
#
|
1379
1396
|
def on_call_false(context)
|
@@ -1391,7 +1408,7 @@ module Oga
|
|
1391
1408
|
# such attribute).
|
1392
1409
|
#
|
1393
1410
|
# @param [Oga::XML::NodeSet] context
|
1394
|
-
# @param [
|
1411
|
+
# @param [AST::Node] language
|
1395
1412
|
# @return [TrueClass|FalseClass]
|
1396
1413
|
#
|
1397
1414
|
def on_call_lang(context, language)
|
@@ -1425,7 +1442,7 @@ module Oga
|
|
1425
1442
|
# Using the expression `sum(root/*)` the return value would be `3.0`.
|
1426
1443
|
#
|
1427
1444
|
# @param [Oga::XML::NodeSet] context
|
1428
|
-
# @param [
|
1445
|
+
# @param [AST::Node] expression
|
1429
1446
|
# @return [Float]
|
1430
1447
|
#
|
1431
1448
|
def on_call_sum(context, expression)
|
@@ -1450,7 +1467,7 @@ module Oga
|
|
1450
1467
|
# and then returns that number as a float.
|
1451
1468
|
#
|
1452
1469
|
# @param [Oga::XML::NodeSet] context
|
1453
|
-
# @param [
|
1470
|
+
# @param [AST::Node] expression
|
1454
1471
|
# @return [Float]
|
1455
1472
|
#
|
1456
1473
|
def on_call_floor(context, expression)
|
@@ -1466,7 +1483,7 @@ module Oga
|
|
1466
1483
|
# and then returns that number as a float.
|
1467
1484
|
#
|
1468
1485
|
# @param [Oga::XML::NodeSet] context
|
1469
|
-
# @param [
|
1486
|
+
# @param [AST::Node] expression
|
1470
1487
|
# @return [Float]
|
1471
1488
|
#
|
1472
1489
|
def on_call_ceiling(context, expression)
|
@@ -1482,7 +1499,7 @@ module Oga
|
|
1482
1499
|
# then returns that number as a float.
|
1483
1500
|
#
|
1484
1501
|
# @param [Oga::XML::NodeSet] context
|
1485
|
-
# @param [
|
1502
|
+
# @param [AST::Node] expression
|
1486
1503
|
# @return [Float]
|
1487
1504
|
#
|
1488
1505
|
def on_call_round(context, expression)
|
@@ -1494,7 +1511,7 @@ module Oga
|
|
1494
1511
|
##
|
1495
1512
|
# Processes an `(int)` node.
|
1496
1513
|
#
|
1497
|
-
# @param [
|
1514
|
+
# @param [AST::Node] ast_node
|
1498
1515
|
# @param [Oga::XML::NodeSet] context
|
1499
1516
|
# @return [Float]
|
1500
1517
|
#
|
@@ -1505,7 +1522,7 @@ module Oga
|
|
1505
1522
|
##
|
1506
1523
|
# Processes an `(float)` node.
|
1507
1524
|
#
|
1508
|
-
# @param [
|
1525
|
+
# @param [AST::Node] ast_node
|
1509
1526
|
# @param [Oga::XML::NodeSet] context
|
1510
1527
|
# @return [Float]
|
1511
1528
|
#
|
@@ -1516,7 +1533,7 @@ module Oga
|
|
1516
1533
|
##
|
1517
1534
|
# Processes a `(string)` node.
|
1518
1535
|
#
|
1519
|
-
# @param [
|
1536
|
+
# @param [AST::Node] ast_node
|
1520
1537
|
# @param [Oga::XML::NodeSet] context
|
1521
1538
|
# @return [String]
|
1522
1539
|
#
|
@@ -1528,7 +1545,7 @@ module Oga
|
|
1528
1545
|
# Processes a variable reference. If the variable is not defined an error
|
1529
1546
|
# is raised.
|
1530
1547
|
#
|
1531
|
-
# @param [
|
1548
|
+
# @param [AST::Node] ast_node
|
1532
1549
|
# @param [Oga::XML::NodeSet] context
|
1533
1550
|
# @return [Mixed]
|
1534
1551
|
# @raise [RuntimeError]
|
@@ -1548,7 +1565,7 @@ module Oga
|
|
1548
1565
|
# in the supplied node set, or the first node in the current context.
|
1549
1566
|
#
|
1550
1567
|
# @param [Oga::XML::NodeSet] context
|
1551
|
-
# @param [
|
1568
|
+
# @param [AST::Node] expression
|
1552
1569
|
# @return [Oga::XML::Node]
|
1553
1570
|
#
|
1554
1571
|
def function_node(context, expression = nil)
|
@@ -1596,7 +1613,7 @@ module Oga
|
|
1596
1613
|
end
|
1597
1614
|
|
1598
1615
|
##
|
1599
|
-
# Checks if a given {Oga::XML::Node} instance matches a
|
1616
|
+
# Checks if a given {Oga::XML::Node} instance matches a `AST::Node`
|
1600
1617
|
# instance.
|
1601
1618
|
#
|
1602
1619
|
# This method can use both "test" and "type-test" nodes. In case of
|
@@ -1614,7 +1631,7 @@ module Oga
|
|
1614
1631
|
# For both the name and namespace a wildcard (`*`) can be used.
|
1615
1632
|
#
|
1616
1633
|
# @param [Oga::XML::Node] xml_node
|
1617
|
-
# @param [
|
1634
|
+
# @param [AST::Node] ast_node
|
1618
1635
|
# @return [Oga::XML::NodeSet]
|
1619
1636
|
#
|
1620
1637
|
def node_matches?(xml_node, ast_node)
|
@@ -1645,7 +1662,7 @@ module Oga
|
|
1645
1662
|
|
1646
1663
|
##
|
1647
1664
|
# @param [Oga::XML::Node] xml_node
|
1648
|
-
# @param [
|
1665
|
+
# @param [AST::Node] ast_node
|
1649
1666
|
# @return [TrueClass|FalseClass]
|
1650
1667
|
#
|
1651
1668
|
def type_matches?(xml_node, ast_node)
|
@@ -1744,6 +1761,26 @@ module Oga
|
|
1744
1761
|
def current_node_set
|
1745
1762
|
return @node_sets.last
|
1746
1763
|
end
|
1764
|
+
|
1765
|
+
##
|
1766
|
+
# Returns the root node of `node`, or `node` itself if its a Document.
|
1767
|
+
#
|
1768
|
+
# @param [Oga::XML::Node|Oga::XML::Document] node
|
1769
|
+
# @return [Oga::XML::Node|Oga::XML::Document]
|
1770
|
+
#
|
1771
|
+
def root_node(node)
|
1772
|
+
return node.respond_to?(:root_node) ? node.root_node : node
|
1773
|
+
end
|
1774
|
+
|
1775
|
+
##
|
1776
|
+
# Returns the parent node of `node`, or `node` itself if its a Document.
|
1777
|
+
#
|
1778
|
+
# @param [Oga::XML::Node|Oga::XML::Document] node
|
1779
|
+
# @return [Oga::XML::Node|Oga::XML::Document]
|
1780
|
+
#
|
1781
|
+
def parent_node(node)
|
1782
|
+
return node.respond_to?(:parent) ? node.parent : node
|
1783
|
+
end
|
1747
1784
|
end # Evaluator
|
1748
1785
|
end # XPath
|
1749
1786
|
end # Oga
|