saxon-rb 0.4.0-java → 0.7.2-java

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +429 -42
  3. data/.ruby-version +1 -1
  4. data/.yardopts +1 -0
  5. data/Gemfile +2 -2
  6. data/README.md +358 -10
  7. data/Rakefile +237 -7
  8. data/docs/templates/plugin.rb +73 -0
  9. 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
  10. data/lib/saxon-rb.rb +0 -0
  11. data/lib/{saxon_jars.rb → saxon-rb_jars.rb} +2 -2
  12. data/lib/saxon.rb +13 -0
  13. data/lib/saxon/axis_iterator.rb +8 -1
  14. data/lib/saxon/configuration.rb +16 -13
  15. data/lib/saxon/document_builder.rb +216 -5
  16. data/lib/saxon/feature_flags.rb +11 -0
  17. data/lib/saxon/feature_flags/errors.rb +8 -0
  18. data/lib/saxon/feature_flags/helpers.rb +15 -0
  19. data/lib/saxon/feature_flags/version.rb +100 -0
  20. data/lib/saxon/item_type.rb +129 -89
  21. data/lib/saxon/item_type/lexical_string_conversion.rb +214 -59
  22. data/lib/saxon/item_type/value_to_ruby.rb +25 -0
  23. data/lib/saxon/loader.rb +6 -1
  24. data/lib/saxon/nokogiri.rb +78 -0
  25. data/lib/saxon/occurrence_indicator.rb +32 -3
  26. data/lib/saxon/processor.rb +50 -5
  27. data/lib/saxon/qname.rb +37 -2
  28. data/lib/saxon/s9api.rb +5 -0
  29. data/lib/saxon/sequence_type.rb +131 -0
  30. data/lib/saxon/serializer.rb +3 -137
  31. data/lib/saxon/serializer/destination.rb +80 -0
  32. data/lib/saxon/serializer/object.rb +93 -0
  33. data/lib/saxon/serializer/output_properties.rb +83 -0
  34. data/lib/saxon/source.rb +207 -71
  35. data/lib/saxon/version.rb +7 -1
  36. data/lib/saxon/version/library.rb +89 -0
  37. data/lib/saxon/xdm.rb +7 -0
  38. data/lib/saxon/xdm/array.rb +16 -0
  39. data/lib/saxon/xdm/atomic_value.rb +10 -2
  40. data/lib/saxon/xdm/empty_sequence.rb +13 -0
  41. data/lib/saxon/xdm/external_object.rb +1 -0
  42. data/lib/saxon/xdm/function_item.rb +1 -0
  43. data/lib/saxon/xdm/item.rb +7 -0
  44. data/lib/saxon/xdm/map.rb +38 -0
  45. data/lib/saxon/xdm/node.rb +50 -1
  46. data/lib/saxon/xdm/sequence_like.rb +15 -0
  47. data/lib/saxon/xdm/value.rb +21 -5
  48. data/lib/saxon/xpath.rb +9 -0
  49. data/lib/saxon/xpath/compiler.rb +37 -2
  50. data/lib/saxon/xpath/executable.rb +53 -28
  51. data/lib/saxon/xpath/static_context.rb +25 -40
  52. data/lib/saxon/xpath/variable_declaration.rb +16 -49
  53. data/lib/saxon/xslt.rb +12 -0
  54. data/lib/saxon/xslt/compiler.rb +75 -6
  55. data/lib/saxon/xslt/evaluation_context.rb +30 -4
  56. data/lib/saxon/xslt/executable.rb +206 -29
  57. data/lib/saxon/xslt/invocation.rb +97 -0
  58. data/saxon-rb.gemspec +3 -3
  59. metadata +22 -10
  60. data/saxon.gemspec +0 -30
@@ -3,6 +3,7 @@ require_relative '../qname'
3
3
 
4
4
  module Saxon
5
5
  module XSLT
6
+ # @api private
6
7
  # Represents the evaluation context for an XSLT compiler, and stylesheets
7
8
  # compiled using one. {EvaluationContext}s are immutable.
8
9
  class EvaluationContext
@@ -47,11 +48,12 @@ module Saxon
47
48
  end
48
49
  end
49
50
 
51
+ # @api public
50
52
  # Provides the hooks for constructing a {EvaluationContext} with a DSL.
51
- # @api private
52
53
  class DSL
53
54
  include Common
54
55
 
56
+ # @api private
55
57
  # Create an instance based on the args hash, and execute the passed in Proc/lambda against it using <tt>#instance_exec</tt> and return a
56
58
  # new {EvaluationContext} with the results
57
59
  # @param block [Proc] a Proc/lambda (or <tt>to_proc</tt>'d containing DSL calls
@@ -130,6 +132,7 @@ module Saxon
130
132
 
131
133
  include Common
132
134
 
135
+ # @api private
133
136
  # Executes the Proc/lambda passed in with a new instance of
134
137
  # {EvaluationContext} as <tt>self</tt>, allowing the DSL methods to be
135
138
  # called in a DSL-ish way
@@ -140,23 +143,46 @@ module Saxon
140
143
  DSL.define(block)
141
144
  end
142
145
 
143
- attr_reader :default_collation, :static_parameters, :global_parameters, :initial_template_parameters, :initial_template_tunnel_parameters
144
146
 
147
+ # @return [String] The default collation URI as a String
148
+ attr_reader :default_collation
149
+ # @return [Hash<Saxon::QName => Saxon::XDM::Value>] All the static parameters
150
+ attr_reader :static_parameters
151
+ # @return [Hash<Saxon::QName => Saxon::XDM::Value>] All the global parameters
152
+ attr_reader :global_parameters
153
+ # @return [Hash<Saxon::QName => Saxon::XDM::Value>] All the initial template parameters
154
+ attr_reader :initial_template_parameters
155
+ # @return [Hash<Saxon::QName => Saxon::XDM::Value>] All the initial template parameters with tunnelling = "yes"
156
+ attr_reader :initial_template_tunnel_parameters
157
+
158
+ # @api private
159
+ # When passed a Proc, create a new EvaluationContext based on this one, with the same DSL available as in {.define}.
160
+ #
161
+ # When passed {nil}, simply return the EvaluationContext unaltered.
145
162
  def define(block)
146
163
  block.nil? ? self : DSL.define(block, args_hash)
147
164
  end
148
165
  end
149
166
 
167
+ # Error raised when a global and static parameter of the same name are
168
+ # declared
150
169
  class GlobalAndStaticParameterClashError < StandardError
151
170
  end
152
171
 
172
+ # parameter shorthand name/value-to-full QName/XDM::Value helper module
153
173
  module ParameterHelper
174
+ # process shorthand parameter hash into fully-qualified QName / Value hash
175
+ # @param parameters [Hash<String, Saxon::QName => Object>]
176
+ # @return [Hash<Saxon::QName => Saxon::XDM::Value>]
177
+ # @see Saxon::QName.resolve() for more about the QName resolution process
178
+ # @see Saxon::XDM.Value() for more about the conversion of Object into XDM Values
154
179
  def self.process_parameters(parameters)
155
- Hash[parameters.map { |qname, value|
180
+ parameters.map { |qname, value|
156
181
  [Saxon::QName.resolve(qname), Saxon::XDM.Value(value)]
157
- }]
182
+ }.to_h
158
183
  end
159
184
 
185
+ # generate Java Map from fully qualified parameter hash
160
186
  def self.to_java(parameters)
161
187
  Hash[parameters.map { |k,v| [k.to_java, v.to_java] }].to_java
162
188
  end
@@ -1,14 +1,60 @@
1
1
  require 'forwardable'
2
2
  require_relative 'evaluation_context'
3
+ require_relative 'invocation'
3
4
  require_relative '../serializer'
4
5
  require_relative '../xdm'
5
6
  require_relative '../qname'
7
+ require_relative '../feature_flags'
6
8
 
7
9
  module Saxon
8
10
  module XSLT
9
11
  # Represents a compiled XSLT stylesheet ready to be executed
12
+ #
13
+ # Once you have a compiled stylesheet, then it can be executed against a
14
+ # source document in a variety of ways.
15
+ #
16
+ # First, you can use the traditional *apply templates* ,method, which was
17
+ # the only way in XSLT 1.
18
+ #
19
+ # input = Saxon::Source.create('input.xml')
20
+ # result = xslt.apply_templates(input)
21
+ #
22
+ # Next, you can call a specific named template (new in XSLT 2).
23
+ #
24
+ # result = xslt.call_template('template-name')
25
+ #
26
+ # Note that there's no input document here. If your XSLT needs a global
27
+ # context item set when you invoke it via a named template, then you can do
28
+ # that, too:
29
+ #
30
+ # input = processor.XML('input.xml')
31
+ # result = xslt.call_template('template-name', {
32
+ # global_context_item: input
33
+ # })
34
+ #
35
+ # Global and initial template parameters can be set at compiler creation
36
+ # time, compile time, or execution time.
37
+ #
38
+ # Initial template parameters relate to parameters passed to the *first*
39
+ # template run (either the first template matched when called with
40
+ # {Executable#apply_templates}, or the named template called with
41
+ # {Executable#call_template}).
42
+ #
43
+ # <b>Initial template parameters</b> are essentially implied +<xsl:with-parameter
44
+ # tunnel="no">+ elements. <b>Initial template tunnel parameters</b> are implied
45
+ # +<xsl:with-parameter tunnel="yes">+ elements.
46
+ #
47
+ # xslt.apply_templates(input, {
48
+ # global_parameters: {'param' => 'global value'},
49
+ # initial_template_parameters: {'param' => 'other value'},
50
+ # initial_template_tunnel_parameters: {'param' => 'tunnel value'}
51
+ # })
52
+ #
53
+ # Remember that if you need to use a parameter name which uses a namespace
54
+ # prefix, you must use an explicit {Saxon::QName} to refer to it.
10
55
  class Executable
11
56
  extend Forwardable
57
+ extend Saxon::FeatureFlags::Helpers
12
58
 
13
59
  attr_reader :evaluation_context
14
60
  private :evaluation_context
@@ -24,16 +70,111 @@ module Saxon
24
70
 
25
71
  def_delegators :evaluation_context, :global_parameters, :initial_template_parameters, :initial_template_tunnel_parameters
26
72
 
73
+ # Run the XSLT by applying templates against the provided {Saxon::Source}
74
+ # or {Saxon::XDM::Node}.
75
+ #
76
+ # @note Any {QName}s supplied as strings MUST be resolvable as a QName
77
+ # without extra information, so they must be prefix-less (so, 'name', and
78
+ # never 'ns:name')
79
+ #
80
+ # @param source [Saxon::Source, Saxon::XDM::Node] the Source or Node that
81
+ # will be used as the global context item
82
+ # @param opts [Hash] a hash of options for invoking the transformation
83
+ # @option opts [Boolean] :raw (false) Whether the transformation should be
84
+ # executed 'raw', because it is expected to return a simple XDM Value
85
+ # (like a number, or plain text) and not an XML document.
86
+ # @option opts [String, Saxon::QName] :mode The initial mode to use when
87
+ # processing starts.
88
+ # @option opts [Hash<String, Saxon::QName => Object>] :global_parameters
89
+ # Additional global parameters to set. Setting already-defined
90
+ # parameters will replace their value for this invocation of the XSLT
91
+ # only, it won't affect the {XSLT::Compiler}'s context.
92
+ # @option opts [Hash<String, Saxon::QName => Object>]
93
+ # :initial_template_parameters Additional parameters to pass to the
94
+ # first template matched. Setting already-defined parameters will
95
+ # replace their value for this invocation of the XSLT only, it won't
96
+ # affect the {XSLT::Compiler}'s context.
97
+ # @option opts [Hash<String, Saxon::QName => Object>]
98
+ # :initial_template_tunnel_parameters Additional tunnelling parameters
99
+ # to pass to the first template matched. Setting already-defined
100
+ # parameters will replace their value for this invocation of the XSLT
101
+ # only, it won't affect the {XSLT::Compiler}'s context.
102
+ # @return [Saxon::XSLT::Invocation] the transformation result
27
103
  def apply_templates(source, opts = {})
28
104
  transformation(opts).apply_templates(source)
29
105
  end
30
106
 
31
- def call_template(template_name, opts = {})
107
+ # Run the XSLT by calling the named template.
108
+ #
109
+ # @note Any {QName}s supplied as Strings (e.g. for the template name)
110
+ # MUST be resolvable as a QName without extra information, so they must be
111
+ # prefix-less (so, 'name', and never 'ns:name')
112
+ #
113
+ # @param template_name [String, Saxon::QName, nil] the name of the
114
+ # template to be invoked. Passing +nil+ will invoke the default named
115
+ # template (+xsl:default-template+)
116
+ # @param opts [Hash] a hash of options for invoking the transformation
117
+ # @option opts [Boolean] :raw (false) Whether the transformation should be
118
+ # executed 'raw', because it is expected to return a simple XDM Value
119
+ # (like a number, or plain text) and not an XML document.
120
+ # @option opts [String, Saxon::QName] :mode The name of the initial mode
121
+ # to use when processing starts.
122
+ # @option opts [Hash<String, Saxon::QName => Object>] :global_parameters
123
+ # Additional global parameters to set. Setting already-defined
124
+ # parameters will replace their value for this invocation of the XSLT
125
+ # only, it won't affect the {XSLT::Compiler}'s context.
126
+ # @option opts [Hash<String, Saxon::QName => Object>]
127
+ # :initial_template_parameters Additional parameters to pass to the
128
+ # first template matched. Setting already-defined parameters will
129
+ # replace their value for this invocation of the XSLT only, it won't
130
+ # affect the {XSLT::Compiler}'s context.
131
+ # @option opts [Hash<String, Saxon::QName => Object>]
132
+ # :initial_template_tunnel_parameters Additional tunnelling parameters
133
+ # to pass to the first template matched. Setting already-defined
134
+ # parameters will replace their value for this invocation of the XSLT
135
+ # only, it won't affect the {XSLT::Compiler}'s context.
136
+ # @return [Saxon::XSLT::Invocation] the transformation result
137
+ def call_template(template_name = nil, opts = {})
32
138
  transformation(opts).call_template(template_name)
33
139
  end
34
140
 
141
+ # Invoke a named function in the XSLT.
142
+ #
143
+ # @note Function name {QName}s have to have prefixes, so they can't be
144
+ # supplied as {::String}s. Any other {QName}s supplied as {::String}s (e.g.
145
+ # for the template name) MUST be resolvable as a QName without extra
146
+ # information, so they must be prefix-less (so, 'name', and never
147
+ # 'ns:name')
148
+ # @note the function you're calling needs to be have been defined with
149
+ # +visibility="public"+ or +visibility="final"+
150
+ #
151
+ # @param function_name [Saxon::QName] the name of the function to be
152
+ # invoked.
153
+ # @param opts [Hash] a hash of options for invoking the transformation
154
+ # @option opts [Boolean] :raw (false) Whether the transformation should be
155
+ # executed 'raw', because it is expected to return a simple XDM Value
156
+ # (like a number, or plain text) and not an XML document.
157
+ # @option opts [Hash<String, Saxon::QName => Object>] :global_parameters
158
+ # Additional global parameters to set. Setting already-defined
159
+ # parameters will replace their value for this invocation of the XSLT
160
+ # only, it won't affect the {XSLT::Compiler}'s context.
161
+ # @return [Saxon::XSLT::Invocation] the transformation result
162
+ def call_function(function_name, opts = {})
163
+ args = opts.fetch(:args, [])
164
+ transformation(opts.reject { |k, v| k == :args }).call_function(function_name, args)
165
+ end
166
+
167
+ # Create a {Serializer::Object} configured using the options that were set
168
+ # by +<xsl:output>+.
169
+ #
170
+ # @return [Saxon::Serializer::Object] the Serializer
171
+ def serializer
172
+ Saxon::Serializer::Object.new(@s9_xslt_executable.load30.newSerializer)
173
+ end
174
+ requires_saxon_version :serializer, '>= 9.9'
175
+
35
176
  # @return [net.sf.saxon.s9api.XsltExecutable] the underlying Saxon
36
- # <tt>XsltExecutable</tt>
177
+ # +XsltExecutable+
37
178
  def to_java
38
179
  @s9_xslt_executable
39
180
  end
@@ -69,22 +210,23 @@ module Saxon
69
210
  end
70
211
  end
71
212
 
72
- class Result
73
- attr_reader :xdm_value
213
+ # @api private
214
+ # Represents a loaded XSLT transformation ready to be applied against a
215
+ # context node.
216
+ class Transformation
217
+ # A list of valid option names for the transform
218
+ VALID_OPTS = [:raw, :mode, :global_context_item, :global_parameters, :initial_template_parameters, :initial_template_tunnel_parameters]
74
219
 
75
- def initialize(xdm_value, s9_transformer)
76
- @xdm_value, @s9_transformer = xdm_value, s9_transformer
77
- end
220
+ attr_reader :s9_transformer, :opts
221
+ private :s9_transformer, :opts
78
222
 
79
- def to_s
80
- serializer = Serializer.new(@s9_transformer.newSerializer)
81
- serializer.serialize(xdm_value.to_java)
223
+ # Return the default initial template namne for XSLT 3 named-template invocation
224
+ # @return [Saxon::QName] the default initial template QName
225
+ def self.default_initial_template
226
+ @default_initial_template ||= Saxon::QName.clark('{http://www.w3.org/1999/XSL/Transform}initial-template')
82
227
  end
83
- end
84
-
85
- class Transformation
86
- attr_reader :s9_transformer, :opts
87
228
 
229
+ # @api private
88
230
  def initialize(args)
89
231
  @s9_transformer = args.fetch(:s9_transformer)
90
232
  @destination = args.fetch(:destination, nil)
@@ -94,36 +236,54 @@ module Saxon
94
236
  @raw = false
95
237
  end
96
238
 
239
+ # Apply templates to Source, using all the context set up when we were
240
+ # created.
97
241
  def apply_templates(source)
98
- transformation_result(:applyTemplates, source)
242
+ transformation_invocation(:applyTemplates, source.to_java)
99
243
  end
100
244
 
245
+ # Call the named template, using all the context set up when we were
246
+ # created.
101
247
  def call_template(template_name)
102
- transformation_result(:callTemplate, Saxon::QName.resolve(template_name))
248
+ transformation_invocation(:callTemplate, resolve_template_name(template_name))
249
+ end
250
+
251
+ # Call the named function, using all the context set up when we were
252
+ # created.
253
+ def call_function(function_name, args)
254
+ function_name = Saxon::QName.resolve(function_name).to_java
255
+ transformation_invocation(:callFunction, function_name, function_args(args))
103
256
  end
104
257
 
105
258
  private
106
259
 
107
- def transformation_result(invocation_method, invocation_arg)
260
+ def transformation_invocation(invocation_method, *invocation_args)
108
261
  set_opts!
109
- transformer_args = [invocation_method, invocation_arg.to_java, destination].compact
110
- Result.new(result_xdm_value(s9_transformer.send(*transformer_args)), s9_transformer)
262
+ XSLT::Invocation.new(s9_transformer, invocation_lambda(invocation_method, invocation_args), raw?)
111
263
  end
112
264
 
113
- def result_xdm_value(transformer_return_value)
114
- XDM.Value(
115
- transformer_return_value.nil? ? destination.getXdmNode : transformer_return_value
116
- )
265
+ def invocation_lambda(invocation_method, invocation_args)
266
+ ->(destination) {
267
+ if destination.nil?
268
+ s9_transformer.send(invocation_method, *invocation_args)
269
+ else
270
+ s9_transformer.send(invocation_method, *invocation_args, destination.to_java)
271
+ end
272
+ }
117
273
  end
118
274
 
119
- def destination
120
- @destination ||= begin
121
- Saxon::S9API::XdmDestination.new unless raw?
122
- end
275
+ def resolve_template_name(template_name)
276
+ return self.class.default_initial_template.to_java if template_name.nil?
277
+ Saxon::QName.resolve(template_name).to_java
278
+ end
279
+
280
+ def function_args(args = [])
281
+ args.map { |val| Saxon::XDM.Value(val).to_java }.to_java(S9API::XdmValue)
123
282
  end
124
283
 
125
284
  def set_opts!
126
285
  opts.each do |opt, value|
286
+ raise BadOptionError, opt unless VALID_OPTS.include?(opt)
127
287
  send(opt, value)
128
288
  end
129
289
  end
@@ -140,16 +300,33 @@ module Saxon
140
300
  s9_transformer.setInitialMode(Saxon::QName.resolve(mode_name).to_java)
141
301
  end
142
302
 
303
+ def global_context_item(xdm_item)
304
+ s9_transformer.setGlobalContextItem(xdm_item.to_java)
305
+ end
306
+
143
307
  def global_parameters(parameters)
144
308
  s9_transformer.setStylesheetParameters(XSLT::ParameterHelper.to_java(parameters))
145
309
  end
146
310
 
147
311
  def initial_template_parameters(parameters)
148
- s9_transformer.setInitialTemplateParameters(XSLT::ParameterHelper.to_java(parameters) , false)
312
+ s9_transformer.setInitialTemplateParameters(XSLT::ParameterHelper.to_java(parameters), false)
149
313
  end
150
314
 
151
315
  def initial_template_tunnel_parameters(parameters)
152
- s9_transformer.setInitialTemplateParameters(XSLT::ParameterHelper.to_java(parameters) , true)
316
+ s9_transformer.setInitialTemplateParameters(XSLT::ParameterHelper.to_java(parameters), true)
317
+ end
318
+ end
319
+
320
+ # Raised if a bad option name is passed in the options hash to
321
+ # Executable#apply_templates et al
322
+ class BadOptionError < StandardError
323
+ def initialize(option_name)
324
+ @option_name = option_name
325
+ end
326
+
327
+ # return error message including the option name
328
+ def to_s
329
+ "Option :#{@option_name} is not a recognised option."
153
330
  end
154
331
  end
155
332
  end
@@ -0,0 +1,97 @@
1
+ require_relative '../serializer'
2
+ require_relative '../xdm/value'
3
+
4
+
5
+ module Saxon
6
+ module XSLT
7
+ # Represents the invocation of a compiled and loaded transformation,
8
+ # providing an idiomatic way to send the result a transformation to a
9
+ # particular Destination, or to serialize it directly to a file, string, or
10
+ # IO.
11
+ class Invocation
12
+ attr_reader :s9_transformer, :invocation_lambda
13
+ private :s9_transformer, :invocation_lambda
14
+
15
+ # @api private
16
+ def initialize(s9_transformer, invocation_lambda, raw)
17
+ @s9_transformer, @invocation_lambda, @raw = s9_transformer, invocation_lambda, raw
18
+ end
19
+
20
+ # Serialize the result to a string using the options specified in
21
+ # +<xsl:output/>+ in the XSLT
22
+ #
23
+ # @return [String] the serialized result of the transformation
24
+ def to_s
25
+ serializer_destination.serialize
26
+ end
27
+
28
+ # Serialize the result of the transformation. When called with a
29
+ # block, the block will be executed via instance-exec so that output
30
+ # properties can be set, e.g.
31
+ #
32
+ # result.serialize {
33
+ # output_property[:indent] = 'yes'
34
+ # }
35
+ #
36
+ # @overload serialize(io)
37
+ # Serialize the transformation to an IO
38
+ # @param [File, IO] io The IO to serialize to
39
+ # @return [nil]
40
+ # @yield the passed block bound via instance-exec to the new serializer
41
+ # @overload serialize(path)
42
+ # Serialize the transformation to file <tt>path</tt>
43
+ # @param [String, Pathname] path The path of the file to serialize to
44
+ # @return [nil]
45
+ # @yield the passed block bound via instance-exec to the new serializer
46
+ # @overload serialize
47
+ # Serialize the transformation to a String
48
+ # @return [String] The serialized XdmValue
49
+ def serialize(path_or_io = nil, &block)
50
+ serializer_destination(&block).serialize(path_or_io)
51
+ end
52
+
53
+ # Return the result of the transformation as an XDM Value, either as it is
54
+ # returned (if the XSLT::Executable was created with :raw => true), or
55
+ # wrapped in a Document node and sequence normalized.
56
+ #
57
+ # @return [Saxon::XDM::Value] the XDM value returned by the transformation
58
+ def xdm_value
59
+ if raw?
60
+ XDM.Value(invocation_lambda.call(nil))
61
+ else
62
+ invocation_lambda.call(s9_xdm_destination)
63
+ XDM.Value(s9_xdm_destination.getXdmNode)
64
+ end
65
+ end
66
+
67
+ # Send the result of the transformation to the supplied Destination
68
+ #
69
+ # @param s9_destination [net.sf.saxon.s9api.Destination] the Saxon
70
+ # destination to use
71
+ # @return [nil]
72
+ def to_destination(s9_destination)
73
+ invocation_lambda.call(s9_destination)
74
+ nil
75
+ end
76
+
77
+ # Whether the transformation was invoked as a 'raw' transformation, where
78
+ # an XDM Value result will be returned without being wrapped in a Document
79
+ # node, and without sequence normalization.
80
+ #
81
+ # @return [Boolean] whether the transformation was invoked 'raw' or not
82
+ def raw?
83
+ @raw
84
+ end
85
+
86
+ private
87
+
88
+ def serializer_destination(&block)
89
+ Saxon::Serializer::Destination.new(s9_transformer.newSerializer, invocation_lambda, &block)
90
+ end
91
+
92
+ def s9_xdm_destination
93
+ @s9_xdm_destination ||= Saxon::S9API::XdmDestination.new
94
+ end
95
+ end
96
+ end
97
+ end