saxon 0.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,68 @@
1
+ require_relative '../item_type'
2
+ require_relative '../occurrence_indicator'
3
+
4
+ module Saxon
5
+ module XPath
6
+ # Represents an XPath variable declaration in the static context of a compiled XPath, providing an idiomatic Ruby way to deal with these.
7
+ class VariableDeclaration
8
+ # @return [Saxon::QName]
9
+ attr_reader :qname
10
+ # @return [Saxon::ItemType]
11
+ attr_reader :item_type
12
+ # @return [net.sf.saxon.s9api.OccurrenceIndicator]
13
+ attr_reader :occurrences
14
+
15
+ # @param opts [Hash]
16
+ # @option opts [Saxon::QName] :qname The name of the variable as a {Saxon::QName}
17
+ def initialize(opts = {})
18
+ raise VariableDeclarationError, opts.keys if opts.keys.length > 2
19
+ @qname = opts.fetch(:qname)
20
+ @item_type, @occurrences = extract_type_decl(opts.reject { |k, v| k == :qname })
21
+ end
22
+
23
+ # VariableDeclarations compare equal if their qname, item_type, and occurrences are equal
24
+ # @param other [Saxon::VariableDeclaration]
25
+ # @return [Boolean]
26
+ def ==(other)
27
+ VariableDeclaration === other && qname == other.qname && item_type == other.item_type && occurrences == other.occurrences
28
+ end
29
+
30
+ # @api private
31
+ def compiler_args
32
+ [qname.to_java, item_type.to_java, occurrences]
33
+ end
34
+
35
+ private
36
+
37
+ def self.valid_opt_keys
38
+ @valid_opt_keys ||= [:qname] + Saxon::OccurrenceIndicator.indicator_names
39
+ end
40
+
41
+ def extract_type_decl(type_decl)
42
+ raise VariableDeclarationError, type_decl.keys if type_decl.length > 1
43
+ unless (type_decl.keys - Saxon::OccurrenceIndicator.indicator_names).empty?
44
+ raise VariableDeclarationError, type_decl.keys
45
+ end
46
+
47
+ return [Saxon::ItemType.get_type('item()'), Saxon::OccurrenceIndicator.zero_or_more] if type_decl.empty?
48
+ occurrence, type = type_decl.first
49
+ [Saxon::ItemType.get_type(type), Saxon::OccurrenceIndicator.send(occurrence)]
50
+ end
51
+ end
52
+
53
+ # Raised when an attempt to declare a variable is made using an occurrence
54
+ # indicator that does not exist
55
+ class VariableDeclarationError < StandardError
56
+ attr_reader :keys
57
+
58
+ def initialize(keys)
59
+ @keys = keys
60
+ end
61
+
62
+ # reports allowable occurrence indicator keys and what was actually passed in
63
+ def to_s
64
+ "requires :qname, and optionally one of #{Saxon::OccurrenceIndicator.indicator_names}, was passed #{keys.join(', ')}"
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,8 @@
1
+ require_relative './xslt/compiler'
2
+
3
+ module Saxon
4
+ # Classes for compiling, configuring, and executing XSLT transformations
5
+ # against XDM nodes or documents
6
+ module XSLT
7
+ end
8
+ end
@@ -0,0 +1,61 @@
1
+ require 'forwardable'
2
+ require_relative './static_context'
3
+ # require_relative './executable'
4
+
5
+ module Saxon
6
+ module XSLT
7
+ # Compiles XSLT stylesheets so they can be executed
8
+ class Compiler
9
+ # Create a new <tt>XSLT::Compiler</tt> using the supplied Processor.
10
+ # Passing a block gives access to a DSL for setting up the compiler's
11
+ # static context.
12
+ #
13
+ # @param processor [Saxon::Processor] the {Saxon::Processor} to use
14
+ # @yield An XSLT compiler DSL block
15
+ # @return [Saxon::XSLT::Compiler] the new compiler instance
16
+ def self.create(processor, &block)
17
+ static_context = XSLT::StaticContext.define(block)
18
+ new(processor.to_java, static_context)
19
+ end
20
+
21
+ extend Forwardable
22
+
23
+ attr_reader :static_context
24
+ private :static_context
25
+
26
+ # @api private
27
+ # @param s9_processor [net.sf.saxon.s9api.Processor] the Saxon
28
+ # <tt>Processor</tt> to wrap
29
+ # @param static_context [Saxon::XPath::StaticContext] the static context
30
+ # XPaths compiled using this compiler will have
31
+ def initialize(s9_processor, static_context)
32
+ @s9_processor, @static_context = s9_processor, static_context
33
+ end
34
+
35
+ def_delegators :static_context, :default_collation
36
+ # @!attribute [r] declared_collations
37
+ # @return [Hash<String => java.text.Collator>] declared collations as URI => Collator hash
38
+ # @!attribute [r] default_collation
39
+ # @return [String] the URI of the default declared collation
40
+
41
+ # @param expression [String] the expression to compile
42
+ # @return [Saxon::XSLT::Executable] the executable query
43
+ def compile(expression)
44
+ Saxon::XSLT::Executable.new(new_compiler.compile(expression), static_context)
45
+ end
46
+
47
+ def create(&block)
48
+ new_static_context = static_context.define(block)
49
+ self.class.new(@s9_processor, new_static_context)
50
+ end
51
+
52
+ private
53
+
54
+ def new_compiler
55
+ compiler = @s9_processor.newXsltCompiler
56
+ compiler.declareDefaultCollation(default_collation) unless default_collation.nil?
57
+ compiler
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,127 @@
1
+ require_relative 'static_context'
2
+ require_relative '../serializer'
3
+ require_relative '../xdm_value'
4
+ require_relative '../qname'
5
+
6
+ module Saxon
7
+ module XSLT
8
+ # Represents a compiled XPaGth query ready to be executed
9
+ class Executable
10
+ # @return [XSLT::StaticContext] the XPath's static context
11
+ attr_reader :static_context
12
+
13
+ # @api private
14
+ # @param s9_xslt_executable [net.sf.saxon.s9api.XsltExecutable] the
15
+ # Saxon compiled XPath object
16
+ # @param static_context [XPath::StaticContext] the XPath's static
17
+ # context
18
+ def initialize(s9_xslt_executable, static_context)
19
+ @s9_xslt_executable, @static_context = s9_xslt_executable, static_context
20
+ end
21
+
22
+ def apply_templates(source, opts = {})
23
+ transformation(opts).apply_templates(source)
24
+ end
25
+
26
+ def call_template(template_name, opts = {})
27
+ transformation(opts).call_template(template_name)
28
+ end
29
+
30
+ # @return [net.sf.saxon.s9api.XsltExecutable] the underlying Saxon
31
+ # <tt>XsltExecutable</tt>
32
+ def to_java
33
+ @s9_xslt_executable
34
+ end
35
+
36
+ private
37
+
38
+ def transformation(opts)
39
+ Transformation.new(opts.merge({
40
+ s9_transformer: @s9_xslt_executable.load30,
41
+ }))
42
+ end
43
+ end
44
+
45
+ class Result
46
+ attr_reader :xdm_value
47
+
48
+ def initialize(xdm_value, s9_transformer)
49
+ @xdm_value, @s9_transformer = xdm_value, s9_transformer
50
+ end
51
+
52
+ def to_s
53
+ serializer = Serializer.new(@s9_transformer.newSerializer)
54
+ serializer.serialize(xdm_value.to_java)
55
+ end
56
+ end
57
+
58
+ class Transformation
59
+ attr_reader :s9_transformer, :opts
60
+
61
+ def initialize(args)
62
+ @s9_transformer = args.fetch(:s9_transformer)
63
+ @destination = args.fetch(:destination, nil)
64
+ @opts = args.reject { |opt, _|
65
+ [:s9_transformer, :destination].include?(opt)
66
+ }
67
+ @raw = false
68
+ end
69
+
70
+ def apply_templates(source)
71
+ transformation_result(:applyTemplates, source)
72
+ end
73
+
74
+ def call_template(template_name)
75
+ transformation_result(:callTemplate, resolve_qname(template_name))
76
+ end
77
+
78
+ private
79
+
80
+ def transformation_result(invocation_method, invocation_arg)
81
+ set_opts!
82
+ transformer_args = [invocation_method, invocation_arg.to_java, destination].compact
83
+ Result.new(result_xdm_value(s9_transformer.send(*transformer_args)), s9_transformer)
84
+ end
85
+
86
+ def result_xdm_value(transformer_return_value)
87
+ XdmValue.wrap_s9_xdm_value(
88
+ transformer_return_value.nil? ? destination.getXdmNode : transformer_return_value
89
+ )
90
+ end
91
+
92
+ def destination
93
+ @destination ||= begin
94
+ Saxon::S9API::XdmDestination.new unless raw?
95
+ end
96
+ end
97
+
98
+ def set_opts!
99
+ opts.each do |opt, value|
100
+ send(opt, value)
101
+ end
102
+ end
103
+
104
+ def raw(value)
105
+ @raw = value
106
+ end
107
+
108
+ def raw?
109
+ @raw
110
+ end
111
+
112
+ def mode(mode_name)
113
+ s9_transformer.setInitialMode(resolve_qname(mode_name).to_java)
114
+ end
115
+
116
+ def resolve_qname(qname)
117
+ case qname
118
+ when Saxon::QName
119
+ qname
120
+ else
121
+ raise Saxon::QName::PrefixedStringWithoutNSURIError if qname.to_s.include?(':')
122
+ Saxon::QName.create(local_name: qname.to_s)
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,69 @@
1
+ require_relative '../qname'
2
+ module Saxon
3
+ module XSLT
4
+ # Represents the static context for an XSLT compiler. {StaticContext}s are immutable.
5
+ class StaticContext
6
+ # methods used by both {StaticContext} and {StaticContext::DSL}
7
+ module Common
8
+ # @param args [Hash]
9
+ # @option args [Hash<String => java.text.Collator>] :declared_collations Hash of URI => Collator bindings
10
+ # @option args [String] :default_collation URI of the default collation
11
+ def initialize(args = {})
12
+ @default_collation = args.fetch(:default_collation, nil).freeze
13
+ end
14
+
15
+ # returns the context details in a hash suitable for initializing a new one
16
+ # @return [Hash<Symbol => Hash,null>] the args hash
17
+ def args_hash
18
+ {
19
+ default_collation: @default_collation
20
+ }
21
+ end
22
+ end
23
+
24
+ # Provides the hooks for constructing a {StaticContext} with a DSL.
25
+ # @api private
26
+ class DSL
27
+ include Common
28
+
29
+ # 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
30
+ # new {StaticContext} with the results
31
+ # @param block [Proc] a Proc/lambda (or <tt>to_proc</tt>'d containing DSL calls
32
+ # @return [Saxon::XPath::StaticContext]
33
+ def self.define(block, args = {})
34
+ dsl = new(args)
35
+ dsl.instance_exec(&block) unless block.nil?
36
+ StaticContext.new(dsl.args_hash)
37
+ end
38
+
39
+ # Set the default Collation to use. This should be one of the special
40
+ # collation URIs Saxon recognises, or one that has been registered
41
+ # using Saxon::Processor#declare_collations on the Processor that
42
+ # created the {XSLT::Compiler} this context is for.
43
+ #
44
+ # @param collation_uri [String] The URI of the Collation to set as the default
45
+ def default_collation(collation_uri)
46
+ @default_collation = collation_uri
47
+ end
48
+ end
49
+
50
+ include Common
51
+
52
+ # Executes the Proc/lambda passed in with a new instance of
53
+ # {StaticContext} as <tt>self</tt>, allowing the DSL methods to be
54
+ # called in a DSL-ish way
55
+ #
56
+ # @param block [Proc] the block of DSL calls to be executed
57
+ # @return [Saxon::XSLT::StaticContext] the static context created by the block
58
+ def self.define(block)
59
+ DSL.define(block)
60
+ end
61
+
62
+ attr_reader :default_collation
63
+
64
+ def define(block)
65
+ DSL.define(block, args_hash)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,10 @@
1
+ # this is a generated file, to avoid over-writing it just delete this comment
2
+ begin
3
+ require 'jar_dependencies'
4
+ rescue LoadError
5
+ require 'net/sf/saxon/Saxon-HE/9.9.1-2/Saxon-HE-9.9.1-2.jar'
6
+ end
7
+
8
+ if defined? Jars
9
+ require_jar 'net.sf.saxon', 'Saxon-HE', '9.9.1-2'
10
+ end
@@ -0,0 +1,38 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'saxon/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'saxon'
8
+ spec.version = Saxon::VERSION
9
+ spec.authors = ['Matt Patterson']
10
+ spec.email = ['matt@werkstatt.io']
11
+
12
+ spec.description = %q{Wraps the Saxon 9.9 XML and XSLT library so you can process, transform, query, and generate XML documents using XSLT 3, XQuery, and XPath 3.1. The HE open-source version is bundled, but you can use the paid-for PE and EE versions of the Java library with this gem as well.
13
+
14
+ It aims to provide an idiomatic Ruby wrapper around all of Saxon's features.}
15
+ spec.summary = %q{Saxon 9.9 for JRuby, with an idiomatic Ruby API}
16
+ spec.homepage = "https://github.com/fidothe/saxon-rb"
17
+ spec.license = 'MIT'
18
+ spec.platform = 'java'
19
+
20
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
+ f.match(%r{^(test|spec|features)/})
22
+ end
23
+ spec.bindir = 'exe'
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ['lib']
26
+
27
+ spec.requirements << 'jar net.sf.saxon, Saxon-HE, 9.9.1-2'
28
+
29
+ spec.add_development_dependency 'bundler', '~> 2.0'
30
+ spec.add_development_dependency 'jar-dependencies'
31
+ spec.add_development_dependency 'rake', '~> 12.0'
32
+ spec.add_development_dependency 'rspec', '~> 3.0'
33
+ spec.add_development_dependency 'vcr', '~> 4.0'
34
+ spec.add_development_dependency 'addressable', '~> 2.4.0'
35
+ spec.add_development_dependency 'webmock', '~> 2.3.2'
36
+ spec.add_development_dependency 'yard', '~> 0.9.12'
37
+ spec.add_development_dependency 'simplecov', '~> 0.15'
38
+ end
metadata ADDED
@@ -0,0 +1,215 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: saxon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: java
6
+ authors:
7
+ - Matt Patterson
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-04-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '2.0'
19
+ name: bundler
20
+ prerelease: false
21
+ type: :development
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ name: jar-dependencies
34
+ prerelease: false
35
+ type: :development
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '12.0'
47
+ name: rake
48
+ prerelease: false
49
+ type: :development
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '12.0'
55
+ - !ruby/object:Gem::Dependency
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '3.0'
61
+ name: rspec
62
+ prerelease: false
63
+ type: :development
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '4.0'
75
+ name: vcr
76
+ prerelease: false
77
+ type: :development
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.0'
83
+ - !ruby/object:Gem::Dependency
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: 2.4.0
89
+ name: addressable
90
+ prerelease: false
91
+ type: :development
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 2.4.0
97
+ - !ruby/object:Gem::Dependency
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: 2.3.2
103
+ name: webmock
104
+ prerelease: false
105
+ type: :development
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 2.3.2
111
+ - !ruby/object:Gem::Dependency
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 0.9.12
117
+ name: yard
118
+ prerelease: false
119
+ type: :development
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.9.12
125
+ - !ruby/object:Gem::Dependency
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '0.15'
131
+ name: simplecov
132
+ prerelease: false
133
+ type: :development
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.15'
139
+ description: |-
140
+ Wraps the Saxon 9.9 XML and XSLT library so you can process, transform, query, and generate XML documents using XSLT 3, XQuery, and XPath 3.1. The HE open-source version is bundled, but you can use the paid-for PE and EE versions of the Java library with this gem as well.
141
+
142
+ It aims to provide an idiomatic Ruby wrapper around all of Saxon's features.
143
+ email:
144
+ - matt@werkstatt.io
145
+ executables: []
146
+ extensions: []
147
+ extra_rdoc_files: []
148
+ files:
149
+ - ".gitignore"
150
+ - ".rspec"
151
+ - ".ruby-version"
152
+ - ".travis.yml"
153
+ - CODE_OF_CONDUCT.md
154
+ - Gemfile
155
+ - LICENSE.txt
156
+ - README.md
157
+ - Rakefile
158
+ - bin/console
159
+ - bin/setup
160
+ - lib/net/sf/saxon/Saxon-HE/9.9.1-2/Saxon-HE-9.9.1-2.jar
161
+ - lib/saxon.rb
162
+ - lib/saxon/axis_iterator.rb
163
+ - lib/saxon/configuration.rb
164
+ - lib/saxon/document_builder.rb
165
+ - lib/saxon/item_type.rb
166
+ - lib/saxon/jaxp.rb
167
+ - lib/saxon/loader.rb
168
+ - lib/saxon/occurrence_indicator.rb
169
+ - lib/saxon/parse_options.rb
170
+ - lib/saxon/processor.rb
171
+ - lib/saxon/qname.rb
172
+ - lib/saxon/s9api.rb
173
+ - lib/saxon/serializer.rb
174
+ - lib/saxon/source.rb
175
+ - lib/saxon/version.rb
176
+ - lib/saxon/xdm_atomic_value.rb
177
+ - lib/saxon/xdm_node.rb
178
+ - lib/saxon/xdm_value.rb
179
+ - lib/saxon/xpath.rb
180
+ - lib/saxon/xpath/compiler.rb
181
+ - lib/saxon/xpath/executable.rb
182
+ - lib/saxon/xpath/static_context.rb
183
+ - lib/saxon/xpath/variable_declaration.rb
184
+ - lib/saxon/xslt.rb
185
+ - lib/saxon/xslt/compiler.rb
186
+ - lib/saxon/xslt/executable.rb
187
+ - lib/saxon/xslt/static_context.rb
188
+ - lib/saxon_jars.rb
189
+ - saxon.gemspec
190
+ homepage: https://github.com/fidothe/saxon-rb
191
+ licenses:
192
+ - MIT
193
+ metadata: {}
194
+ post_install_message:
195
+ rdoc_options: []
196
+ require_paths:
197
+ - lib
198
+ required_ruby_version: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
203
+ required_rubygems_version: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ requirements:
209
+ - jar net.sf.saxon, Saxon-HE, 9.9.1-2
210
+ rubyforge_project:
211
+ rubygems_version: 2.7.6
212
+ signing_key:
213
+ specification_version: 4
214
+ summary: Saxon 9.9 for JRuby, with an idiomatic Ruby API
215
+ test_files: []