saxon-rb 0.5.0-java → 0.6.0-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc90ab039f1169f43563e5036774ae66149c78c7b0027ea2b0cb72cafcd0b5e3
4
- data.tar.gz: 18490756712240e5d3869d73dd788ae980178ef3b79ffb41330a8e7db80c1b47
3
+ metadata.gz: 2e9afbc5a2644034bc285b3c3cd4e78f852b715d7a096ff8f7a6386730501598
4
+ data.tar.gz: fe9c135af6356690fcca7b4f1dc2d9656cce44018806c3b5f6c9f4b6407c576d
5
5
  SHA512:
6
- metadata.gz: d20fdd7e7b7fb7842d3d6059bb176903195fc911e46f4ffaecfa22d5dcc4e8919dadce8fe85feb5ab84045484d97f97ed3217330d77a4454a31c0b5efe1fc220
7
- data.tar.gz: c39dd5d7fa31cf2e58cddc002f51d218543f38eb270c10e618105eb559c1467cd338ca68abe317d4574427ef2461c1f3112c7f0acf0e2dd9f9463c67992b8660
6
+ metadata.gz: c59e0f986b8bbf4de77b18feba99a61c8e724df537679b0e674bc142a0d2b476026bb01579dcd2ec6e9b4f246493db3b892fbe7e997848eb06bf5c7bd8e2f5ea
7
+ data.tar.gz: 182d383aced898a376d37eaedb60ff80461910d3451e119f2bf6e97ebe37d8c64e600563ba968efec22f49ae02f025ec3725f00a2cb9af10813af8e20fc13100
data/README.md CHANGED
@@ -194,6 +194,47 @@ result = xslt.call_template('template-name', {
194
194
 
195
195
  Global and initial template parameters can be set at compiler creation time, compile time, or execution time. See [Setting parameters](#label-Setting+parameters) for details.
196
196
 
197
+ To serialize the document you can, of course, just call `#to_s` on the result:
198
+
199
+ ```ruby
200
+ result = xslt.apply_templates(input)
201
+ puts result.to_s #=> '<?xml version="1.0"...'
202
+ ```
203
+
204
+ You can also serialize directly to a file path or to any IO instance.
205
+
206
+ ```ruby
207
+ result = xslt.apply_templates(input)
208
+ result.serialize('/path/to/output.xml')
209
+
210
+ result_2 = xslt.apply_templates(input)
211
+ result_2.serialize($stderr)
212
+ ```
213
+
214
+ You can override serialization options that were set by `<xsl:output/>` in your XSLT:
215
+
216
+ ```ruby
217
+ result = xslt.apply_templates(input)
218
+ result.serialize('/path/to/output.xml') {
219
+ output_property[:indent] = 'yes'
220
+ }
221
+ ```
222
+
223
+ You can also obtain the result of the transform as an XDM Value:
224
+
225
+ ```ruby
226
+ result = xslt.apply_templates(input)
227
+ result.xdm_value #=> #<Saxon::XDM::Node...>
228
+ ```
229
+
230
+ You also have easy access to provide an instance of a class implementing Saxon's `net.sf.saxon.s9api.Destination` interface:
231
+
232
+ ```ruby
233
+ dom_document = javax.xml.parsers.DocumentBuilderFactory.newInstance.builder.newDocument
234
+ destination = Saxon::S9API::DOMDestination.new(dom_document)
235
+ result = xslt.apply_templates(input).to_destination(destination)
236
+ ```
237
+
197
238
  #### Setting parameters
198
239
 
199
240
  There are four kinds of parameters you can set: *Static parameters*, which are
@@ -44,7 +44,7 @@ module Saxon
44
44
  # @return [String] a serialization of the the input document
45
45
  def serialize(doc_node)
46
46
  s9_transformer = @s9_xslt_executable.load30
47
- serializer = Saxon::Serializer.new(s9_transformer.newSerializer)
47
+ serializer = Saxon::Serializer::Object.new(s9_transformer.newSerializer)
48
48
  serializer.serialize(doc_node.to_java)
49
49
  end
50
50
 
@@ -4,6 +4,7 @@ require 'saxon/configuration'
4
4
  require 'saxon/document_builder'
5
5
  require 'saxon/xpath'
6
6
  require 'saxon/xslt'
7
+ require 'saxon/serializer'
7
8
 
8
9
  module Saxon
9
10
  # Saxon::Processor wraps the S9API::Processor object. This is the object
@@ -82,6 +83,17 @@ module Saxon
82
83
  Saxon::XSLT::Compiler.create(self, &block)
83
84
  end
84
85
 
86
+ # Generate a new +Serializer+ for directly serializing XDM Values that uses
87
+ # this +Processor+. +Serializer+s are effectively one-shot objects, and
88
+ # shouldn't be reused.
89
+ #
90
+ # @yield the block passed will be called bound to the serializer instance. See
91
+ # {Saxon::Serializer::Object.create}
92
+ # @return [Saxon::Serializer::Object]
93
+ def serializer(&block)
94
+ Saxon::Serializer::Object.create(self, &block)
95
+ end
96
+
85
97
  # @return [net.sf.saxon.s9api.Processor] The underlying Saxon processor
86
98
  def to_java
87
99
  @s9_processor
@@ -0,0 +1,80 @@
1
+ require_relative '../s9api'
2
+ require_relative './output_properties'
3
+
4
+ module Saxon
5
+ module Serializer
6
+ # A Saxon Serializer to be used as a Destination for a transformation rather
7
+ # than being directly called with existing XDM objects
8
+ class Destination
9
+ include OutputProperties
10
+
11
+ attr_reader :s9_serializer, :invocation_lambda
12
+
13
+ # @api private
14
+ def initialize(s9_serializer, invocation_lambda, &block)
15
+ @s9_serializer, @invocation_lambda = s9_serializer, invocation_lambda
16
+ if block_given?
17
+ instance_exec(&block)
18
+ end
19
+ end
20
+
21
+ # @overload serialize(io)
22
+ # Serialize the transformation to an IO
23
+ # @param [File, IO] io The IO to serialize to
24
+ # @return [nil]
25
+ # @overload serialize(path)
26
+ # Serialize the transformation to file <tt>path</tt>
27
+ # @param [String, Pathname] path The path of the file to serialize to
28
+ # @return [nil]
29
+ # @overload serialize
30
+ # Serialize the transformation to a String
31
+ # @return [String] The serialized XdmValue
32
+ def serialize(io_or_path = nil)
33
+ case io_or_path
34
+ when nil
35
+ serialize_to_string
36
+ when String, Pathname
37
+ serialize_to_file(io_or_path)
38
+ else
39
+ serialize_to_io(io_or_path)
40
+ end
41
+ end
42
+
43
+ # @return [Saxon::S9API::Serializer] The underlying Saxon Serializer object
44
+ def to_java
45
+ s9_serializer
46
+ end
47
+
48
+ private
49
+
50
+ def run_transform!
51
+ invocation_lambda.call(self.to_java)
52
+ end
53
+
54
+ def serialize_to_string
55
+ str_encoding = output_property.fetch(:encoding, Encoding.default_internal || Encoding.default_external)
56
+ StringIO.open { |io|
57
+ io.binmode
58
+ set_output_io(io)
59
+ run_transform!
60
+ io.string.force_encoding(str_encoding)
61
+ }
62
+ end
63
+
64
+ def serialize_to_io(io)
65
+ set_output_io(io)
66
+ run_transform!
67
+ end
68
+
69
+ def set_output_io(io)
70
+ s9_serializer.setOutputStream(io.to_outputstream)
71
+ end
72
+
73
+ def serialize_to_file(path)
74
+ file = Java::JavaIO::File.new(path.to_s)
75
+ s9_serializer.setOutputFile(file)
76
+ run_transform!
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,93 @@
1
+ require_relative '../s9api'
2
+ require_relative './output_properties'
3
+ require 'stringio'
4
+
5
+ module Saxon
6
+ module Serializer
7
+ # A Saxon Serializer to be used directly with XDM Values rather than being
8
+ # called as a Destination for a transformation.
9
+ class Object
10
+ # Create a serializer from the passed in +Processor+. When called with a
11
+ # block, the block will be executed via instance-exec so that output
12
+ # properties can be set, e.g.
13
+ #
14
+ # Serializer::Object.create(processor) {
15
+ # output_property[:indent] = 'yes'
16
+ # }
17
+ #
18
+ # @param processor [Saxon::Processor] the processor to create this
19
+ # +Serializer::Object+ from
20
+ # @yield the passed block bound via instance-exec to the new serializer
21
+ def self.create(processor, &block)
22
+ new(processor.to_java.newSerializer, &block)
23
+ end
24
+
25
+ include OutputProperties
26
+
27
+ attr_reader :s9_serializer
28
+ private :s9_serializer
29
+
30
+ # @api private
31
+ def initialize(s9_serializer, &block)
32
+ @s9_serializer = s9_serializer
33
+ if block_given?
34
+ instance_exec(&block)
35
+ end
36
+ end
37
+
38
+ # @overload serialize(xdm_value, io)
39
+ # Serialize an XdmValue to an IO
40
+ # @param [Saxon::XdmValue] xdm_value The XdmValue to serialize
41
+ # @param [File, IO] io The IO to serialize to
42
+ # @return [nil]
43
+ # @overload serialize(xdm_value, path)
44
+ # Serialize an XdmValue to file <tt>path</tt>
45
+ # @param [Saxon::XdmValue] xdm_value The XdmValue to serialize
46
+ # @param [String, Pathname] path The path of the file to serialize to
47
+ # @return [nil]
48
+ # @overload serialize(xdm_value)
49
+ # Serialize an XdmValue to a String
50
+ # @param [Saxon::XdmValue] xdm_value The XdmValue to serialize
51
+ # @return [String] The serialized XdmValue
52
+ def serialize(xdm_value, io_or_path = nil)
53
+ case io_or_path
54
+ when nil
55
+ serialize_to_string(xdm_value)
56
+ when String, Pathname
57
+ serialize_to_file(xdm_value, io_or_path)
58
+ else
59
+ serialize_to_io(xdm_value, io_or_path)
60
+ end
61
+ end
62
+
63
+ # @return [Saxon::S9API::Serializer] The underlying Saxon Serializer object
64
+ def to_java
65
+ s9_serializer
66
+ end
67
+
68
+ private
69
+
70
+ def serialize_to_io(xdm_value, io)
71
+ s9_serializer.setOutputStream(io.to_outputstream)
72
+ s9_serializer.serializeXdmValue(xdm_value.to_java)
73
+ nil
74
+ end
75
+
76
+ def serialize_to_string(xdm_value)
77
+ str_encoding = output_property.fetch(:encoding, Encoding.default_internal || Encoding.default_external)
78
+ StringIO.open { |io|
79
+ io.binmode
80
+ serialize_to_io(xdm_value, io)
81
+ io.string.force_encoding(str_encoding)
82
+ }
83
+ end
84
+
85
+ def serialize_to_file(xdm_value, path)
86
+ file = Java::JavaIO::File.new(path.to_s)
87
+ s9_serializer.setOutputFile(file)
88
+ s9_serializer.serializeXdmValue(xdm_value.to_java)
89
+ nil
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,83 @@
1
+ module Saxon
2
+ module Serializer
3
+ # Manage access to the serialization properties of this serializer, with
4
+ # hash-like access.
5
+ #
6
+ # Properties can be set explicitly through this API, or via XSLT or XQuery
7
+ # serialization options like +<xsl:output>+.
8
+ #
9
+ # Properties set explicitly here will override properties set through the
10
+ # document by +<xsl:output>+.
11
+ module OutputProperties
12
+ # @return [Saxon::Serializer::OutputProperties] hash-like access to the Output Properties
13
+ def output_property
14
+ @output_property ||= OutputProperties::Accessor.new(s9_serializer)
15
+ end
16
+
17
+ # @api private
18
+ #
19
+ # The private wrapper class that manages getting and setting output
20
+ # properties on a Serializer in an idiomatic Ruby-like way.
21
+ class Accessor
22
+ # @api private
23
+ # Provides mapping between symbols and the underlying Saxon property
24
+ # instances
25
+ def self.output_properties
26
+ @output_properties ||= Hash[
27
+ Saxon::S9API::Serializer::Property.values.map { |property|
28
+ qname = property.getQName
29
+ key = [
30
+ qname.getPrefix,
31
+ qname.getLocalName.tr('-', '_')
32
+ ].reject { |str| str == '' }.join('_').to_sym
33
+ [key, property]
34
+ }
35
+ ]
36
+ end
37
+
38
+ attr_reader :s9_serializer
39
+
40
+ # @api private
41
+ def initialize(s9_serializer)
42
+ @s9_serializer = s9_serializer
43
+ end
44
+
45
+ # @param [Symbol, Saxon::S9API::Serializer::Property] property The property to fetch
46
+ def [](property)
47
+ s9_serializer.getOutputProperty(resolved_property(property))
48
+ end
49
+
50
+ # @param [Symbol, Saxon::S9API::Serializer::Property] property The property to set
51
+ # @param [String] value The string value of the property
52
+ def []=(property, value)
53
+ s9_serializer.setOutputProperty(resolved_property(property), value)
54
+ end
55
+
56
+ # @overload fetch(property)
57
+ # @param [Symbol, Saxon::S9API::Serializer::Property] property The property to fetch
58
+ # @overload fetch(property, default)
59
+ # @param property [Symbol, Saxon::S9API::Serializer::Property] The property to fetch
60
+ # @param default [Object] The value to return if the property is unset
61
+ def fetch(property, default = nil)
62
+ explicit_value = self[property]
63
+ if explicit_value.nil? && !default.nil?
64
+ default
65
+ else
66
+ explicit_value
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def resolved_property(property_key)
73
+ case property_key
74
+ when Symbol
75
+ self.class.output_properties.fetch(property_key)
76
+ else
77
+ property_key
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -1,143 +1,9 @@
1
- require 'saxon/s9api'
2
- require 'stringio'
1
+ require_relative './serializer/destination.rb'
2
+ require_relative './serializer/object.rb'
3
3
 
4
4
  module Saxon
5
5
  # Serialize XDM objects.
6
- class Serializer
7
- # Manage access to the serialization properties of this serializer, with
8
- # hash-like access.
9
- #
10
- # Properties can be set explicitly through this API, or via XSLT or XQuery
11
- # serialization options like `<xsl:output>`.
12
- #
13
- # Properties set explicitly here will override properties set through the
14
- # document like `<xsl:output>`.
15
- class OutputProperties
16
- # @api private
17
- # Provides mapping between symbols and the underlying Saxon property
18
- # instances
19
- def self.output_properties
20
- @output_properties ||= Hash[
21
- Saxon::S9API::Serializer::Property.values.map { |property|
22
- qname = property.getQName
23
- key = [
24
- qname.getPrefix,
25
- qname.getLocalName.tr('-', '_')
26
- ].reject { |str| str == '' }.join('_').to_sym
27
- [key, property]
28
- }
29
- ]
30
- end
31
-
32
- attr_reader :s9_serializer
33
-
34
- # @api private
35
- def initialize(s9_serializer)
36
- @s9_serializer = s9_serializer
37
- end
38
-
39
- # @param [Symbol, Saxon::S9API::Serializer::Property] property The property to fetch
40
- def [](property)
41
- s9_serializer.getOutputProperty(resolved_property(property))
42
- end
43
-
44
- # @param [Symbol, Saxon::S9API::Serializer::Property] property The property to set
45
- # @param [String] value The string value of the property
46
- def []=(property, value)
47
- s9_serializer.setOutputProperty(resolved_property(property), value)
48
- end
49
-
50
- # @overload fetch(property)
51
- # @param [Symbol, Saxon::S9API::Serializer::Property] property The property to fetch
52
- # @overload fetch(property, default)
53
- # @param property [Symbol, Saxon::S9API::Serializer::Property] The property to fetch
54
- # @param default [Object] The value to return if the property is unset
55
- def fetch(property, default = nil)
56
- explicit_value = self[property]
57
- if explicit_value.nil? && !default.nil?
58
- default
59
- else
60
- explicit_value
61
- end
62
- end
63
-
64
- private
65
- def resolved_property(property_key)
66
- case property_key
67
- when Symbol
68
- self.class.output_properties.fetch(property_key)
69
- else
70
- property_key
71
- end
72
- end
73
- end
74
-
75
- attr_reader :s9_serializer
76
- private :s9_serializer
77
-
78
- # @api private
79
- def initialize(s9_serializer)
80
- @s9_serializer = s9_serializer
81
- end
82
-
83
- # @return [Saxon::Serializer::OutputProperties] hash-like access to the Output Properties
84
- def output_property
85
- @output_property ||= OutputProperties.new(s9_serializer)
86
- end
87
-
88
- # @overload serialize(xdm_value, io)
89
- # Serialize an XdmValue to an IO
90
- # @param [Saxon::XdmValue] xdm_value The XdmValue to serialize
91
- # @param [File, IO] io The IO to serialize to
92
- # @return [nil]
93
- # @overload serialize(xdm_value, path)
94
- # Serialize an XdmValue to file <tt>path</tt>
95
- # @param [Saxon::XdmValue] xdm_value The XdmValue to serialize
96
- # @param [String, Pathname] path The path of the file to serialize to
97
- # @return [nil]
98
- # @overload serialize(xdm_value)
99
- # Serialize an XdmValue to a String
100
- # @param [Saxon::XdmValue] xdm_value The XdmValue to serialize
101
- # @return [String] The serialized XdmValue
102
- def serialize(xdm_value, io_or_path = nil)
103
- case io_or_path
104
- when nil
105
- serialize_to_string(xdm_value)
106
- when String, Pathname
107
- serialize_to_file(xdm_value, io_or_path)
108
- else
109
- serialize_to_io(xdm_value, io_or_path)
110
- end
111
- end
112
-
113
- # @return [Saxon::S9API::Serializer] The underlying Saxon Serializer object
114
- def to_java
115
- s9_serializer
116
- end
117
-
118
- private
119
-
120
- def serialize_to_io(xdm_value, io)
121
- s9_serializer.setOutputStream(io.to_outputstream)
122
- s9_serializer.serializeXdmValue(xdm_value.to_java)
123
- nil
124
- end
125
-
126
- def serialize_to_string(xdm_value)
127
- str_encoding = output_property.fetch(:encoding, Encoding.default_internal || Encoding.default_external)
128
- StringIO.open { |io|
129
- io.binmode
130
- serialize_to_io(xdm_value, io)
131
- io.string.force_encoding(str_encoding)
132
- }
133
- end
134
-
135
- def serialize_to_file(xdm_value, path)
136
- file = Java::JavaIO::File.new(path)
137
- s9_serializer.setOutputFile(file)
138
- s9_serializer.serializeXdmValue(xdm_value.to_java)
139
- nil
140
- end
6
+ module Serializer
141
7
  end
142
8
  end
143
9
 
data/lib/saxon/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Saxon
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -33,9 +33,10 @@ module Saxon
33
33
  @node_name = node_name.nil? ? nil : Saxon::QName.new(node_name)
34
34
  end
35
35
 
36
- # What kind of node this is. Returns one of +:element+, +:text+,
37
- # +:attribute+, +:namespace+, +:comment+, +:processing_instruction+, or
38
- # +:comment+
36
+ # What kind of node this is. Returns one of +:document+, +:element+,
37
+ # +:text+, +:attribute+, +:namespace+, +:comment+,
38
+ # +:processing_instruction+, or +:comment+
39
+ #
39
40
  # @return [Symbol] the kind of node this is
40
41
  def node_kind
41
42
  @node_kind ||= case s9_xdm_node.nodeKind
@@ -1,5 +1,6 @@
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'
@@ -96,7 +97,7 @@ module Saxon
96
97
  # to pass to the first template matched. Setting already-defined
97
98
  # parameters will replace their value for this invocation of the XSLT
98
99
  # only, it won't affect the {XSLT::Compiler}'s context.
99
- # @return [Saxon::XSLT::Result] the transformation result
100
+ # @return [Saxon::XSLT::Invocation] the transformation result
100
101
  def apply_templates(source, opts = {})
101
102
  transformation(opts).apply_templates(source)
102
103
  end
@@ -130,7 +131,7 @@ module Saxon
130
131
  # to pass to the first template matched. Setting already-defined
131
132
  # parameters will replace their value for this invocation of the XSLT
132
133
  # only, it won't affect the {XSLT::Compiler}'s context.
133
- # @return [Saxon::XSLT::Result] the transformation result
134
+ # @return [Saxon::XSLT::Invocation] the transformation result
134
135
  def call_template(template_name = nil, opts = {})
135
136
  transformation(opts).call_template(template_name)
136
137
  end
@@ -155,14 +156,14 @@ module Saxon
155
156
  # Additional global parameters to set. Setting already-defined
156
157
  # parameters will replace their value for this invocation of the XSLT
157
158
  # only, it won't affect the {XSLT::Compiler}'s context.
158
- # @return [Saxon::XSLT::Result] the transformation result
159
+ # @return [Saxon::XSLT::Invocation] the transformation result
159
160
  def call_function(function_name, opts = {})
160
161
  args = opts.fetch(:args, [])
161
162
  transformation(opts.reject { |k, v| k == :args }).call_function(function_name, args)
162
163
  end
163
164
 
164
165
  # @return [net.sf.saxon.s9api.XsltExecutable] the underlying Saxon
165
- # <tt>XsltExecutable</tt>
166
+ # +XsltExecutable+
166
167
  def to_java
167
168
  @s9_xslt_executable
168
169
  end
@@ -213,6 +214,7 @@ module Saxon
213
214
  @default_initial_template ||= Saxon::QName.clark('{http://www.w3.org/1999/XSL/Transform}initial-template')
214
215
  end
215
216
 
217
+ # @api private
216
218
  def initialize(args)
217
219
  @s9_transformer = args.fetch(:s9_transformer)
218
220
  @destination = args.fetch(:destination, nil)
@@ -225,57 +227,48 @@ module Saxon
225
227
  # Apply templates to Source, using all the context set up when we were
226
228
  # created.
227
229
  def apply_templates(source)
228
- transformation_result(:applyTemplates, source)
230
+ transformation_invocation(:applyTemplates, source.to_java)
229
231
  end
230
232
 
231
233
  # Call the named template, using all the context set up when we were
232
234
  # created.
233
235
  def call_template(template_name)
234
- transformation_result(:callTemplate, resolve_template_name(template_name))
236
+ transformation_invocation(:callTemplate, resolve_template_name(template_name))
235
237
  end
236
238
 
237
239
  # Call the named function, using all the context set up when we were
238
240
  # created.
239
241
  def call_function(function_name, args)
240
242
  function_name = Saxon::QName.resolve(function_name).to_java
241
- args = function_args(args)
242
- call_function_result(function_name, args)
243
+ transformation_invocation(:callFunction, function_name, function_args(args))
243
244
  end
244
245
 
245
246
  private
246
247
 
247
- def transformation_result(invocation_method, invocation_arg)
248
+ def transformation_invocation(invocation_method, *invocation_args)
248
249
  set_opts!
249
- transformer_args = [invocation_method, invocation_arg.to_java, destination].compact
250
- Result.new(result_xdm_value(s9_transformer.send(*transformer_args)), s9_transformer)
250
+ XSLT::Invocation.new(s9_transformer, invocation_lambda(invocation_method, invocation_args), raw?)
251
251
  end
252
252
 
253
- def call_function_result(name, args)
254
- set_opts!
255
- Result.new(result_xdm_value(s9_transformer.callFunction(*[name, args, destination].compact)), s9_transformer)
256
- end
257
-
258
- def result_xdm_value(transformer_return_value)
259
- XDM.Value(
260
- transformer_return_value.nil? ? destination.getXdmNode : transformer_return_value
261
- )
253
+ def invocation_lambda(invocation_method, invocation_args)
254
+ ->(destination) {
255
+ if destination.nil?
256
+ s9_transformer.send(invocation_method, *invocation_args)
257
+ else
258
+ s9_transformer.send(invocation_method, *invocation_args, destination.to_java)
259
+ end
260
+ }
262
261
  end
263
262
 
264
263
  def resolve_template_name(template_name)
265
- return self.class.default_initial_template if template_name.nil?
266
- Saxon::QName.resolve(template_name)
264
+ return self.class.default_initial_template.to_java if template_name.nil?
265
+ Saxon::QName.resolve(template_name).to_java
267
266
  end
268
267
 
269
268
  def function_args(args = [])
270
269
  args.map { |val| Saxon::XDM.Value(val).to_java }.to_java(S9API::XdmValue)
271
270
  end
272
271
 
273
- def destination
274
- @destination ||= begin
275
- Saxon::S9API::XdmDestination.new unless raw?
276
- end
277
- end
278
-
279
272
  def set_opts!
280
273
  opts.each do |opt, value|
281
274
  raise BadOptionError, opt unless VALID_OPTS.include?(opt)
@@ -312,24 +305,6 @@ module Saxon
312
305
  end
313
306
  end
314
307
 
315
- # Represents the result of a transformation, providing a simple default
316
- # serializer as well
317
- class Result
318
- attr_reader :xdm_value
319
-
320
- # @api private
321
- def initialize(xdm_value, s9_transformer)
322
- @xdm_value, @s9_transformer = xdm_value, s9_transformer
323
- end
324
-
325
- # Serialize the result to a string using the options specified in
326
- # +<xsl:output/>+ in the XSLT
327
- def to_s
328
- serializer = Serializer.new(@s9_transformer.newSerializer)
329
- serializer.serialize(xdm_value.to_java)
330
- end
331
- end
332
-
333
308
  # Raised if a bad option name is passed in the options hash to
334
309
  # Executable#apply_templates et al
335
310
  class BadOptionError < StandardError
@@ -0,0 +1,96 @@
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
+
14
+ # @api private
15
+ def initialize(s9_transformer, invocation_lambda, raw)
16
+ @s9_transformer, @invocation_lambda, @raw = s9_transformer, invocation_lambda, raw
17
+ end
18
+
19
+ # Serialize the result to a string using the options specified in
20
+ # +<xsl:output/>+ in the XSLT
21
+ #
22
+ # @return [String] the serialized result of the transformation
23
+ def to_s
24
+ serializer_destination.serialize
25
+ end
26
+
27
+ # Serialize the result of the transformation. When called with a
28
+ # block, the block will be executed via instance-exec so that output
29
+ # properties can be set, e.g.
30
+ #
31
+ # result.serialize {
32
+ # output_property[:indent] = 'yes'
33
+ # }
34
+ #
35
+ # @overload serialize(io)
36
+ # Serialize the transformation to an IO
37
+ # @param [File, IO] io The IO to serialize to
38
+ # @return [nil]
39
+ # @yield the passed block bound via instance-exec to the new serializer
40
+ # @overload serialize(path)
41
+ # Serialize the transformation to file <tt>path</tt>
42
+ # @param [String, Pathname] path The path of the file to serialize to
43
+ # @return [nil]
44
+ # @yield the passed block bound via instance-exec to the new serializer
45
+ # @overload serialize
46
+ # Serialize the transformation to a String
47
+ # @return [String] The serialized XdmValue
48
+ def serialize(path_or_io = nil, &block)
49
+ serializer_destination(&block).serialize(path_or_io)
50
+ end
51
+
52
+ # Return the result of the transformation as an XDM Value, either as it is
53
+ # returned (if the XSLT::Executable was created with :raw => true), or
54
+ # wrapped in a Document node and sequence normalized.
55
+ #
56
+ # @return [Saxon::XDM::Value] the XDM value returned by the transformation
57
+ def xdm_value
58
+ if raw?
59
+ XDM.Value(invocation_lambda.call(nil))
60
+ else
61
+ invocation_lambda.call(s9_xdm_destination)
62
+ XDM.Value(s9_xdm_destination.getXdmNode)
63
+ end
64
+ end
65
+
66
+ # Send the result of the transformation to the supplied Destination
67
+ #
68
+ # @param destination [net.sf.saxon.s9api.Destination] the Saxon
69
+ # destination to use
70
+ # @return [nil]
71
+ def to_destination(s9_destination)
72
+ invocation_lambda.call(s9_destination)
73
+ nil
74
+ end
75
+
76
+ # Whether the transformation was invoked as a 'raw' transformation, where
77
+ # an XDM Value result will be returned without being wrapped in a Document
78
+ # node, and without sequence normalization.
79
+ #
80
+ # @return [Boolean] whether the transformation was invoked 'raw' or not
81
+ def raw?
82
+ @raw
83
+ end
84
+
85
+ private
86
+
87
+ def serializer_destination(&block)
88
+ Saxon::Serializer::Destination.new(s9_transformer.newSerializer, invocation_lambda, &block)
89
+ end
90
+
91
+ def s9_xdm_destination
92
+ @s9_xdm_destination ||= Saxon::S9API::XdmDestination.new
93
+ end
94
+ end
95
+ end
96
+ end
data/saxon-rb.gemspec CHANGED
@@ -34,6 +34,6 @@ It aims to provide an idiomatic Ruby wrapper around all of Saxon's features.}
34
34
  spec.add_development_dependency 'addressable', '~> 2.4.0'
35
35
  spec.add_development_dependency 'webmock', '~> 2.3.2'
36
36
  spec.add_development_dependency 'yard', '~> 0.9.12'
37
- spec.add_development_dependency 'simplecov', '~> 0.15'
37
+ spec.add_development_dependency 'simplecov', '~> 0.17.1'
38
38
  spec.add_development_dependency 'rspec_junit_formatter'
39
39
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saxon-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: java
6
6
  authors:
7
7
  - Matt Patterson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-01-02 00:00:00.000000000 Z
11
+ date: 2020-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -127,7 +127,7 @@ dependencies:
127
127
  requirements:
128
128
  - - "~>"
129
129
  - !ruby/object:Gem::Version
130
- version: '0.15'
130
+ version: 0.17.1
131
131
  name: simplecov
132
132
  prerelease: false
133
133
  type: :development
@@ -135,7 +135,7 @@ dependencies:
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '0.15'
138
+ version: 0.17.1
139
139
  - !ruby/object:Gem::Dependency
140
140
  requirement: !ruby/object:Gem::Requirement
141
141
  requirements:
@@ -191,6 +191,9 @@ files:
191
191
  - lib/saxon/s9api.rb
192
192
  - lib/saxon/sequence_type.rb
193
193
  - lib/saxon/serializer.rb
194
+ - lib/saxon/serializer/destination.rb
195
+ - lib/saxon/serializer/object.rb
196
+ - lib/saxon/serializer/output_properties.rb
194
197
  - lib/saxon/source.rb
195
198
  - lib/saxon/version.rb
196
199
  - lib/saxon/xdm.rb
@@ -213,6 +216,7 @@ files:
213
216
  - lib/saxon/xslt/compiler.rb
214
217
  - lib/saxon/xslt/evaluation_context.rb
215
218
  - lib/saxon/xslt/executable.rb
219
+ - lib/saxon/xslt/invocation.rb
216
220
  - saxon-rb.gemspec
217
221
  homepage: https://github.com/fidothe/saxon-rb
218
222
  licenses: