saxon-rb 0.4.0-java → 0.5.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +429 -42
- data/Gemfile +2 -2
- data/README.md +317 -10
- data/Rakefile +237 -7
- data/lib/net/sf/saxon/Saxon-HE/{9.9.1-5/Saxon-HE-9.9.1-5.jar → 9.9.1-6/Saxon-HE-9.9.1-6.jar} +0 -0
- data/lib/saxon-rb.rb +1 -0
- data/lib/{saxon_jars.rb → saxon-rb_jars.rb} +2 -2
- data/lib/saxon.rb +13 -0
- data/lib/saxon/axis_iterator.rb +8 -1
- data/lib/saxon/configuration.rb +1 -0
- data/lib/saxon/item_type.rb +12 -17
- data/lib/saxon/item_type/lexical_string_conversion.rb +136 -58
- data/lib/saxon/item_type/value_to_ruby.rb +13 -0
- data/lib/saxon/loader.rb +4 -1
- data/lib/saxon/nokogiri.rb +78 -0
- data/lib/saxon/occurrence_indicator.rb +32 -3
- data/lib/saxon/processor.rb +32 -1
- data/lib/saxon/qname.rb +37 -2
- data/lib/saxon/s9api.rb +5 -0
- data/lib/saxon/sequence_type.rb +131 -0
- data/lib/saxon/source.rb +207 -71
- data/lib/saxon/version.rb +1 -1
- data/lib/saxon/xdm.rb +7 -0
- data/lib/saxon/xdm/array.rb +16 -0
- data/lib/saxon/xdm/atomic_value.rb +7 -1
- data/lib/saxon/xdm/empty_sequence.rb +13 -0
- data/lib/saxon/xdm/external_object.rb +1 -0
- data/lib/saxon/xdm/function_item.rb +1 -0
- data/lib/saxon/xdm/item.rb +7 -0
- data/lib/saxon/xdm/map.rb +38 -0
- data/lib/saxon/xdm/node.rb +19 -1
- data/lib/saxon/xdm/sequence_like.rb +15 -0
- data/lib/saxon/xdm/value.rb +21 -5
- data/lib/saxon/xpath.rb +9 -0
- data/lib/saxon/xpath/compiler.rb +36 -1
- data/lib/saxon/xpath/executable.rb +53 -28
- data/lib/saxon/xpath/static_context.rb +19 -39
- data/lib/saxon/xpath/variable_declaration.rb +16 -49
- data/lib/saxon/xslt.rb +12 -0
- data/lib/saxon/xslt/compiler.rb +75 -6
- data/lib/saxon/xslt/evaluation_context.rb +19 -3
- data/lib/saxon/xslt/executable.rb +204 -14
- data/saxon-rb.gemspec +1 -1
- metadata +9 -7
- data/saxon.gemspec +0 -30
@@ -5,30 +5,43 @@ module Saxon
|
|
5
5
|
module XDM
|
6
6
|
# Represents the empty sequence in XDM
|
7
7
|
class EmptySequence
|
8
|
+
# Returns an instance. Effectively a Singleton because the EmptySequence
|
9
|
+
# is immutable, and empty. An instance is completely interchangeable with
|
10
|
+
# another. The instance is cached, but multiple instances may exist across
|
11
|
+
# threads. We don't prevent that because it's immaterial.
|
12
|
+
# @return [EmptySequence] The empty sequence
|
8
13
|
def self.create
|
9
14
|
@instance ||= new
|
10
15
|
end
|
11
16
|
|
12
17
|
include SequenceLike
|
13
18
|
|
19
|
+
# @return [Enumerator] an enumerator over an empty Array
|
14
20
|
def sequence_enum
|
15
21
|
[].to_enum
|
16
22
|
end
|
17
23
|
|
24
|
+
# @return [Integer] the size of the sequence (always 0)
|
18
25
|
def sequence_size
|
19
26
|
0
|
20
27
|
end
|
21
28
|
|
29
|
+
# All instances of {EmptySequence} are equal to each other.
|
30
|
+
#
|
31
|
+
# @param other [Object] the object to compare self against
|
32
|
+
# @return [Boolean] Whether this object is equal to the other
|
22
33
|
def ==(other)
|
23
34
|
other.class == self.class
|
24
35
|
end
|
25
36
|
|
26
37
|
alias_method :eql?, :==
|
27
38
|
|
39
|
+
# @return [Integer] the hash code. All instances have the same hash code.
|
28
40
|
def hash
|
29
41
|
[].hash
|
30
42
|
end
|
31
43
|
|
44
|
+
# @return [net.sf.saxon.s9api.XDMEmptySequence] the underlying Java empty sequence
|
32
45
|
def to_java
|
33
46
|
@s9_xdm_empty_sequence ||= Saxon::S9API::XdmEmptySequence.getInstance
|
34
47
|
end
|
data/lib/saxon/xdm/item.rb
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
module Saxon
|
2
2
|
module XDM
|
3
|
+
# Create one of the XdmItem-derived XDM objects from the passed in argument.
|
4
|
+
#
|
5
|
+
# Existing XDM::* objects are passed through. s9api.Xdm* Java objects are
|
6
|
+
# wrapped appropriately and returned. Ruby Arrays and Hashes are converted
|
7
|
+
# to {XDM::Array} and {XDM::Map} instances respectively. Ruby values that
|
8
|
+
# respond to +#each+ are converted to an {XDM::Array} (e.g. {Set}). Other
|
9
|
+
# Ruby values are converted to {XDM::AtomicValue}.
|
3
10
|
def self.Item(item)
|
4
11
|
case item
|
5
12
|
when Value, AtomicValue, Node, Array, Map, ExternalObject
|
data/lib/saxon/xdm/map.rb
CHANGED
@@ -5,6 +5,12 @@ module Saxon
|
|
5
5
|
module XDM
|
6
6
|
# Represents an XDM Map
|
7
7
|
class Map
|
8
|
+
# Create an {XDM::Map} from a Ruby Hash, by ensuring each key has been
|
9
|
+
# converted to an {AtomicValue}, and each value has been converted to an
|
10
|
+
# XDM Value of some sort.
|
11
|
+
# @return [XDM::Map] the new Map
|
12
|
+
# @see XDM.AtomicValue
|
13
|
+
# @see XDM.Value
|
8
14
|
def self.create(hash)
|
9
15
|
case hash
|
10
16
|
when Saxon::S9API::XdmMap
|
@@ -30,39 +36,71 @@ module Saxon
|
|
30
36
|
@s9_xdm_map = s9_xdm_map
|
31
37
|
end
|
32
38
|
|
39
|
+
# Compare this Map against another. They're equal if they contain the same
|
40
|
+
# key, value pairs.
|
33
41
|
def ==(other)
|
34
42
|
return false unless other.is_a?(self.class)
|
35
43
|
to_h == other.to_h
|
36
44
|
end
|
37
45
|
|
46
|
+
# Fetch the value for the key given. +key+ is converted to an
|
47
|
+
# {XDM::AtomicValue} if it isn't already one.
|
48
|
+
# @param key [Object, XDM::AtomicValue] the key to retrieve
|
38
49
|
def [](key)
|
39
50
|
cached_hash[XDM.AtomicValue(key)]
|
40
51
|
end
|
41
52
|
|
53
|
+
# Fetch the value for the key given, as {Hash#fetch} would. +key+ is
|
54
|
+
# converted to an {XDM::AtomicValue} if it isn't already one.
|
55
|
+
# @param key [XDM::AtomicValue, Object] the key to retrieve.
|
56
|
+
# @see Hash#fetch
|
42
57
|
def fetch(key, *args, &block)
|
43
58
|
cached_hash.fetch(XDM.AtomicValue(key), *args, &block)
|
44
59
|
end
|
45
60
|
|
61
|
+
# Iterate over the Map as {Hash#each} would
|
62
|
+
# @yieldparam key [XDM::AtomicValue] the key
|
63
|
+
# @yieldparam value [XDM::Value] the value
|
46
64
|
def each(&block)
|
47
65
|
cached_hash.each(&block)
|
48
66
|
end
|
49
67
|
|
68
|
+
# Return a new Map containing only key, value pairs for which the block
|
69
|
+
# returns true.
|
70
|
+
# @yieldparam key [XDM::AtomicValue] the key
|
71
|
+
# @yieldparam value [XDM::Value] the value
|
72
|
+
# @see ::Hash#select
|
50
73
|
def select(&block)
|
51
74
|
self.class.create(each.select(&block).to_h)
|
52
75
|
end
|
53
76
|
|
77
|
+
# Return a new Map containing only key, value pairs for which the block
|
78
|
+
# DOES NOT return true.
|
79
|
+
# @yieldparam key [XDM::AtomicValue] the key
|
80
|
+
# @yieldparam value [XDM::Value] the value
|
81
|
+
# @see ::Hash#reject
|
54
82
|
def reject(&block)
|
55
83
|
self.class.create(each.reject(&block).to_h)
|
56
84
|
end
|
57
85
|
|
86
|
+
# Create a new Map from the result of merging another Map into this one.
|
87
|
+
# In the case of duplicate keys, the value in the provided hash will be
|
88
|
+
# used.
|
89
|
+
# @yieldparam key [XDM::AtomicValue] the key
|
90
|
+
# @yieldparam value [XDM::Value] the value
|
91
|
+
# @return [XDM::Map] the new Map
|
92
|
+
# @see ::Hash#merge
|
58
93
|
def merge(other)
|
59
94
|
self.class.create(to_h.merge(other.to_h))
|
60
95
|
end
|
61
96
|
|
97
|
+
# @return [S9API::XdmMap] the underlying Saxon XdmMap
|
62
98
|
def to_java
|
63
99
|
@s9_xdm_map
|
64
100
|
end
|
65
101
|
|
102
|
+
# a (frozen) Ruby hash containing the keys and values from the Map.
|
103
|
+
# @return [Hash] the Map as a Ruby hash.
|
66
104
|
def to_h
|
67
105
|
cached_hash
|
68
106
|
end
|
data/lib/saxon/xdm/node.rb
CHANGED
@@ -4,7 +4,8 @@ require_relative 'sequence_like'
|
|
4
4
|
|
5
5
|
module Saxon
|
6
6
|
module XDM
|
7
|
-
# An XPath Data Model Node object, representing an XML document, or an
|
7
|
+
# An XPath Data Model Node object, representing an XML document, or an
|
8
|
+
# element or one of the other node chunks in the XDM.
|
8
9
|
class Node
|
9
10
|
include XDM::SequenceLike
|
10
11
|
include XDM::ItemSequenceLike
|
@@ -23,12 +24,19 @@ module Saxon
|
|
23
24
|
@s9_xdm_node
|
24
25
|
end
|
25
26
|
|
27
|
+
# The name of the node, as a {Saxon::QName}, or +nil+ if the node is not
|
28
|
+
# of a kind that has a name
|
29
|
+
# @return [Saxon::QName, null] the name, if there is one
|
26
30
|
def node_name
|
27
31
|
return @node_name if instance_variable_defined?(:@node_name)
|
28
32
|
node_name = s9_xdm_node.getNodeName
|
29
33
|
@node_name = node_name.nil? ? nil : Saxon::QName.new(node_name)
|
30
34
|
end
|
31
35
|
|
36
|
+
# What kind of node this is. Returns one of +:element+, +:text+,
|
37
|
+
# +:attribute+, +:namespace+, +:comment+, +:processing_instruction+, or
|
38
|
+
# +:comment+
|
39
|
+
# @return [Symbol] the kind of node this is
|
32
40
|
def node_kind
|
33
41
|
@node_kind ||= case s9_xdm_node.nodeKind
|
34
42
|
when Saxon::S9API::XdmNodeKind::ELEMENT
|
@@ -48,6 +56,7 @@ module Saxon
|
|
48
56
|
end
|
49
57
|
end
|
50
58
|
|
59
|
+
# Does this Node represent the same underlying node as the other?
|
51
60
|
def ==(other)
|
52
61
|
return false unless other.is_a?(XDM::Node)
|
53
62
|
s9_xdm_node.equals(other.to_java)
|
@@ -55,14 +64,23 @@ module Saxon
|
|
55
64
|
|
56
65
|
alias_method :eql?, :==
|
57
66
|
|
67
|
+
# Compute a hash-code for this {Node}.
|
68
|
+
#
|
69
|
+
# Two {Node}s with the same content will have the same hash code (and will compare using eql?).
|
70
|
+
# @see Object#hash
|
58
71
|
def hash
|
59
72
|
@hash ||= s9_xdm_node.hashCode
|
60
73
|
end
|
61
74
|
|
75
|
+
# Execute the given block for every child node of this
|
76
|
+
# @yieldparam node [Saxon::XDM::Node] the child node
|
62
77
|
def each(&block)
|
63
78
|
axis_iterator(:child).each(&block)
|
64
79
|
end
|
65
80
|
|
81
|
+
# Create an {AxisIterator} over this Node for the given XPath axis
|
82
|
+
# @param axis [Symbol] the axis to iterate along
|
83
|
+
# @see AxisIterator
|
66
84
|
def axis_iterator(axis)
|
67
85
|
AxisIterator.new(self, axis)
|
68
86
|
end
|
@@ -1,14 +1,25 @@
|
|
1
1
|
module Saxon
|
2
2
|
module XDM
|
3
|
+
# Mixin for objects that are XDM Sequence-like in behaviour
|
3
4
|
module SequenceLike
|
5
|
+
# Implementors should return an {Enumerator} over the Sequence. For
|
6
|
+
# {XDM::Value}s, this will just be the items in the sequence. For
|
7
|
+
# XDM::AtomicValue or XDM::Node, this will be a single-item Enumerator so
|
8
|
+
# that Items can be correctly treated as single-item Values.
|
4
9
|
def sequence_enum
|
5
10
|
raise NotImplementedError
|
6
11
|
end
|
7
12
|
|
13
|
+
# Implementors should return the size of the Sequence. For
|
14
|
+
# {XDM::AtomicValue} this will always be 1.
|
15
|
+
# @return [Integer] the sequence size
|
8
16
|
def sequence_size
|
9
17
|
raise NotImplementedError
|
10
18
|
end
|
11
19
|
|
20
|
+
# Return a new XDM::Value from this Sequence with the passed in value
|
21
|
+
# appended to the end.
|
22
|
+
# @return [XDM::Value] the new Value
|
12
23
|
def append(other)
|
13
24
|
XDM::Value.create([self, other])
|
14
25
|
end
|
@@ -17,11 +28,15 @@ module Saxon
|
|
17
28
|
alias_method :+, :append
|
18
29
|
end
|
19
30
|
|
31
|
+
# Mixin for objects that are Sequence-like but only contain a single item,
|
32
|
+
# like {XDM::AtomicValue} or {XDM::Node}
|
20
33
|
module ItemSequenceLike
|
34
|
+
# return a single-item Enumerator containing +self+
|
21
35
|
def sequence_enum
|
22
36
|
[self].to_enum
|
23
37
|
end
|
24
38
|
|
39
|
+
# Returns the sequence size, which will always be 1.
|
25
40
|
def sequence_size
|
26
41
|
1
|
27
42
|
end
|
data/lib/saxon/xdm/value.rb
CHANGED
@@ -19,8 +19,8 @@ module Saxon
|
|
19
19
|
when 0
|
20
20
|
XDM.EmptySequence()
|
21
21
|
when 1
|
22
|
-
if
|
23
|
-
return
|
22
|
+
if value = maybe_xdm_value(items.first)
|
23
|
+
return value
|
24
24
|
end
|
25
25
|
XDM.Item(items.first)
|
26
26
|
else
|
@@ -30,12 +30,25 @@ module Saxon
|
|
30
30
|
|
31
31
|
private
|
32
32
|
|
33
|
-
def maybe_xdm_value(
|
34
|
-
return
|
35
|
-
return
|
33
|
+
def maybe_xdm_value(value)
|
34
|
+
return value if value.is_a?(self)
|
35
|
+
return value if value === XDM.EmptySequence()
|
36
|
+
return XDM.EmptySequence() if value.instance_of?(Saxon::S9API::XdmEmptySequence)
|
37
|
+
return check_for_empty_or_single_item_value(value) if value.instance_of?(Saxon::S9API::XdmValue)
|
36
38
|
false
|
37
39
|
end
|
38
40
|
|
41
|
+
def check_for_empty_or_single_item_value(s9_value)
|
42
|
+
case s9_value.size
|
43
|
+
when 0
|
44
|
+
XDM.EmptySequence()
|
45
|
+
when 1
|
46
|
+
XDM.Item(s9_value.item_at(0))
|
47
|
+
else
|
48
|
+
new(s9_value)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
39
52
|
def wrap_items(items)
|
40
53
|
result = []
|
41
54
|
items.map { |item|
|
@@ -122,10 +135,12 @@ module Saxon
|
|
122
135
|
|
123
136
|
alias_method :enum_for, :to_enum
|
124
137
|
|
138
|
+
# Returns an enumerator over the Sequence
|
125
139
|
def sequence_enum
|
126
140
|
to_enum
|
127
141
|
end
|
128
142
|
|
143
|
+
# @return [Integer] the size of the sequence
|
129
144
|
def sequence_size
|
130
145
|
s9_xdm_value.size
|
131
146
|
end
|
@@ -137,6 +152,7 @@ module Saxon
|
|
137
152
|
@s9_xdm_item = s9_xdm_item
|
138
153
|
end
|
139
154
|
|
155
|
+
# Return the underlying s9api XdmItem
|
140
156
|
def to_java
|
141
157
|
@s9_xdm_item
|
142
158
|
end
|
data/lib/saxon/xpath.rb
CHANGED
@@ -3,6 +3,15 @@ require_relative './xpath/compiler'
|
|
3
3
|
module Saxon
|
4
4
|
# Classes for compiling, configuring, and executing XPath queries against
|
5
5
|
# XDM nodes or documents
|
6
|
+
#
|
7
|
+
# Using an XPath involves creating a compiler, compiling an XPath into an
|
8
|
+
# executable, and then running that XPath executable against an XDM node.
|
9
|
+
#
|
10
|
+
# The easiest way to create an XPath::Compiler instance is by using the {Saxon::Processor#xpath_compiler} method.
|
11
|
+
#
|
12
|
+
# @see Saxon::XPath::Compiler
|
13
|
+
# @see Saxon::XPath::Executable
|
14
|
+
# @see Saxon::Processor#xpath_compiler
|
6
15
|
module XPath
|
7
16
|
end
|
8
17
|
end
|
data/lib/saxon/xpath/compiler.rb
CHANGED
@@ -4,7 +4,36 @@ require_relative './executable'
|
|
4
4
|
|
5
5
|
module Saxon
|
6
6
|
module XPath
|
7
|
-
#
|
7
|
+
# An {XPath::Compiler} turns XPath expressions into executable queries you
|
8
|
+
# can run against XDM Nodes (like XML documents, or parts of XML documents).
|
9
|
+
#
|
10
|
+
# To compile an XPath requires an +XPath::Compiler+ instance. You can create
|
11
|
+
# one by calling {Compiler.create} and passing a {Saxon::Processor}, with an
|
12
|
+
# optional block for context like bound namespaces and declared variables.
|
13
|
+
# Alternately, and much more easily, you can call {Processor#xpath_compiler}
|
14
|
+
# on the {Saxon::Processor} instance you're already working with.
|
15
|
+
#
|
16
|
+
# processor = Saxon::Processor.create
|
17
|
+
# compiler = processor.xpath_compiler {
|
18
|
+
# namespace a: 'http://example.org/a'
|
19
|
+
# variable 'a:var', 'xs:string'
|
20
|
+
# }
|
21
|
+
# # Or...
|
22
|
+
# compiler = Saxon::XPath::Compiler.create(processor) {
|
23
|
+
# namespace a: 'http://example.org/a'
|
24
|
+
# variable 'a:var', 'xs:string'
|
25
|
+
# }
|
26
|
+
# xpath = compiler.compile('//a:element[@attr = $a:var]')
|
27
|
+
# matches = xpath.evaluate(document_node, {
|
28
|
+
# 'a:var' => 'the value'
|
29
|
+
# }) #=> Saxon::XDM::Value
|
30
|
+
#
|
31
|
+
# In order to use prefixed QNames in your XPaths, like +/ns:name/+, then you need
|
32
|
+
# to declare prefix/namespace URI bindings when you create a compiler.
|
33
|
+
#
|
34
|
+
# It's also possible to make use of variables in your XPaths by declaring them at
|
35
|
+
# the compiler creation stage, and then passing in values for them as XPath run
|
36
|
+
# time.
|
8
37
|
class Compiler
|
9
38
|
# Create a new <tt>XPath::Compiler</tt> using the supplied Processor.
|
10
39
|
# Passing a block gives access to a DSL for setting up the compiler's
|
@@ -46,6 +75,12 @@ module Saxon
|
|
46
75
|
Saxon::XPath::Executable.new(new_compiler.compile(expression), static_context)
|
47
76
|
end
|
48
77
|
|
78
|
+
# Allows the creation of a new {Compiler} starting from a copy of this
|
79
|
+
# Compiler's static context. As with {.create}, passing a block gives
|
80
|
+
# access to a DSL for setting up the compiler's static context.
|
81
|
+
#
|
82
|
+
# @yield An {XPath::StaticContext::DSL} block
|
83
|
+
# @return [Saxon::XPath::Compiler] the new compiler instance
|
49
84
|
def create(&block)
|
50
85
|
new_static_context = static_context.define(block)
|
51
86
|
self.class.new(@s9_processor, new_static_context)
|
@@ -2,7 +2,23 @@ require_relative '../xdm'
|
|
2
2
|
|
3
3
|
module Saxon
|
4
4
|
module XPath
|
5
|
-
# Represents a compiled XPath query ready to be executed
|
5
|
+
# Represents a compiled XPath query ready to be executed. An
|
6
|
+
# {XPath::Executable} is created by compiling an XPath expression with
|
7
|
+
# {XPath::Compiler#compile}.
|
8
|
+
#
|
9
|
+
# To run the +XPath::Executable+ you can call {XPath::Executable#evaluate},
|
10
|
+
# to generate an {XDM::Value} of the results, or you can call
|
11
|
+
# {XPath::Executable#as_enum} to return an Enumerator over the results.
|
12
|
+
#
|
13
|
+
# processor = Saxon::Processor.create
|
14
|
+
# compiler = processor.xpath_compiler
|
15
|
+
# xpath = compiler.compile('//element[@attr = $var]')
|
16
|
+
#
|
17
|
+
# matches = xpath.evaluate(document_node, {'var' => 'the value'}) #=> Saxon::XDM::Value
|
18
|
+
#
|
19
|
+
# xpath.as_enum(document_node, {'var' => 'the value'}).each do |node|
|
20
|
+
# ...
|
21
|
+
# end
|
6
22
|
class Executable
|
7
23
|
# @return [XPath::StaticContext] the XPath's static context
|
8
24
|
attr_reader :static_context
|
@@ -16,17 +32,34 @@ module Saxon
|
|
16
32
|
@s9_xpath_executable, @static_context = s9_xpath_executable, static_context
|
17
33
|
end
|
18
34
|
|
19
|
-
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
35
|
+
|
36
|
+
# Evaluate the XPath against the context node given and return an
|
37
|
+
# +Enumerator+ over the result.
|
38
|
+
#
|
39
|
+
# @param context_item [Saxon::XDM::Node, Saxon::XDM::AtomicValue] the item
|
40
|
+
# to be used as the context item for evaluating the XPath from.
|
41
|
+
# @param variables [Hash<Saxon::QName => Saxon::XDM::Value, Saxon::XDM::Node,
|
42
|
+
# Saxon::XDM::AtomicValue>] any variable values to set within the XPath
|
43
|
+
# @return [Enumerator] an Enumerator over the items in the result sequence
|
44
|
+
def as_enum(context_item, variables = {})
|
45
|
+
generate_selector(context_item, variables).iterator.lazy.
|
46
|
+
map { |s9_xdm_object| Saxon::XDM.Value(s9_xdm_object) }
|
47
|
+
end
|
48
|
+
|
49
|
+
# Evaluate the XPath against the context node given and return the result.
|
50
|
+
#
|
51
|
+
# If the result is a single item, then that will be returned directly
|
52
|
+
# (e.g. an {XDM::Node} or an {XDM::AtomicValue}). If the result is an
|
53
|
+
# empty sequence then {XDM::EmptySequence} is returned.
|
54
|
+
#
|
55
|
+
# @param context_item [Saxon::XDM::Node, Saxon::XDM::AtomicValue] the item
|
56
|
+
# to be used as the context item for evaluating the XPath from.
|
57
|
+
# @param variables [Hash<Saxon::QName => Saxon::XDM::Value, Saxon::XDM::Node,
|
58
|
+
# Saxon::XDM::AtomicValue>] any variable values to set within the XPath
|
59
|
+
# @return [Saxon::XDM::Value] the XDM value returned
|
60
|
+
def evaluate(context_item, variables = {})
|
61
|
+
s9_xdm_value = generate_selector(context_item, variables).evaluate
|
62
|
+
Saxon::XDM.Value(s9_xdm_value)
|
30
63
|
end
|
31
64
|
|
32
65
|
# @return [net.sf.saxon.s9api.XPathExecutable] the underlying Saxon
|
@@ -34,24 +67,16 @@ module Saxon
|
|
34
67
|
def to_java
|
35
68
|
@s9_xpath_executable
|
36
69
|
end
|
37
|
-
end
|
38
70
|
|
39
|
-
|
40
|
-
class Result
|
41
|
-
include Enumerable
|
71
|
+
private
|
42
72
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
# Yields <tt>XDM::Node</tt>s from the query result. If no block is passed,
|
51
|
-
# returns an <tt>Enumerator</tt>
|
52
|
-
# @yieldparam xdm_node [Saxon::XDM::Node] the name that is yielded
|
53
|
-
def each(&block)
|
54
|
-
@result_iterator.lazy.map { |s9_xdm_node| Saxon::XDM::Node.new(s9_xdm_node) }.each(&block)
|
73
|
+
def generate_selector(context_item, variables = {})
|
74
|
+
selector = to_java.load
|
75
|
+
selector.setContextItem(context_item.to_java)
|
76
|
+
variables.each do |qname_or_string, value|
|
77
|
+
selector.setVariable(static_context.resolve_variable_qname(qname_or_string).to_java, Saxon::XDM.Value(value).to_java)
|
78
|
+
end
|
79
|
+
selector
|
55
80
|
end
|
56
81
|
end
|
57
82
|
end
|