nokogiri_schematron_builder 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +32 -0
- data/README.md +109 -0
- data/Rakefile +2 -0
- data/WARRANTY.txt +22 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/nokogiri/xml/schematron.rb +8 -0
- data/lib/nokogiri/xml/schematron/assertion.rb +46 -0
- data/lib/nokogiri/xml/schematron/base.rb +143 -0
- data/lib/nokogiri/xml/schematron/internal/core_ext/array.rb +33 -0
- data/lib/nokogiri/xml/schematron/namespace.rb +42 -0
- data/lib/nokogiri/xml/schematron/nodes/base.rb +189 -0
- data/lib/nokogiri/xml/schematron/nodes/context.rb +13 -0
- data/lib/nokogiri/xml/schematron/nodes/permit.rb +24 -0
- data/lib/nokogiri/xml/schematron/nodes/reject.rb +24 -0
- data/lib/nokogiri/xml/schematron/nodes/require.rb +24 -0
- data/lib/nokogiri/xml/schematron/nodes/validations/exclusion.rb +51 -0
- data/lib/nokogiri/xml/schematron/nodes/validations/inclusion.rb +51 -0
- data/lib/nokogiri/xml/schematron/nodes/validations/numericality.rb +142 -0
- data/lib/nokogiri/xml/schematron/paragraph.rb +36 -0
- data/lib/nokogiri/xml/schematron/pattern.rb +150 -0
- data/lib/nokogiri/xml/schematron/rule.rb +53 -0
- data/lib/nokogiri/xml/schematron/schema.rb +85 -0
- data/lib/nokogiri/xml/schematron/version.rb +7 -0
- data/nokogiri_schematron_builder.gemspec +38 -0
- metadata +114 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
require "nokogiri/xml/schematron/base"
|
2
|
+
|
3
|
+
module Nokogiri
|
4
|
+
module XML
|
5
|
+
module Schematron
|
6
|
+
# The internal representation of the +<sch:ns>+ XML element.
|
7
|
+
#
|
8
|
+
# For example:
|
9
|
+
#
|
10
|
+
# namespace = Nokogiri::XML::Schematron::Namespace.new(nil, prefix: "ex", uri: "http://example.com/ns#")
|
11
|
+
# # => #<Nokogiri::XML::Schematron::Namespace:0x00007f8486acd4f8 @parent=nil, @children=[], @options={:prefix=>"ex", :uri=>"http://example.com/ns#"}>
|
12
|
+
# namespace.to_builder.to_xml
|
13
|
+
# # => "<?xml version=\"1.0\"?>\n<sch:ns xmlns:sch=\"http://purl.oclc.org/dsdl/schematron\" prefix=\"ex\" uri=\"http://example.com/ns#\"/>\n"
|
14
|
+
#
|
15
|
+
class Namespace < Nokogiri::XML::Schematron::Base
|
16
|
+
# @!attribute [rw] prefix
|
17
|
+
# @return [String] the value of the +@prefix+ XML attribute.
|
18
|
+
attribute :prefix
|
19
|
+
|
20
|
+
# @!attribute [rw] uri
|
21
|
+
# @return [String] the value of the +@uri+ XML attribute.
|
22
|
+
attribute :uri
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def build!(xml)
|
27
|
+
xml["sch"].send(:ns, %w(prefix uri).inject(xmlns) { |acc, method_name|
|
28
|
+
unless (s = send(method_name.to_sym)).nil?
|
29
|
+
acc[method_name.to_s] = s
|
30
|
+
end
|
31
|
+
|
32
|
+
acc
|
33
|
+
}) do
|
34
|
+
super(xml)
|
35
|
+
end
|
36
|
+
|
37
|
+
return
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require "nokogiri/xml/schematron/base"
|
2
|
+
|
3
|
+
module Nokogiri
|
4
|
+
module XML
|
5
|
+
module Schematron
|
6
|
+
module Nodes
|
7
|
+
# The base class for internal representations of abstract syntax tree
|
8
|
+
# (AST) nodes, where the tree is denested and then used to build a
|
9
|
+
# sequence of zero or more +<sch:rule>+ elements.
|
10
|
+
# @abstract
|
11
|
+
class Base < Nokogiri::XML::Schematron::Base
|
12
|
+
# @return [Hash<String, Nokogiri::XML::Schematron::Nodes::Base>] the hash of child nodes by XPaths.
|
13
|
+
attr_reader :child_node_by_context
|
14
|
+
|
15
|
+
# @return [String] the XPath.
|
16
|
+
attr_accessor :context
|
17
|
+
|
18
|
+
# Create a new +Nodes::Base+ object.
|
19
|
+
#
|
20
|
+
# @param parent [Nokogiri::XML::Schematron::Base] the parent object.
|
21
|
+
# @param context [String] the XPath.
|
22
|
+
# @param options [Hash<Symbol, Object>] the options.
|
23
|
+
# @yieldparam node [Nokogiri::XML::Schematron::Nodes::Base] the +Nodes::Base+ object.
|
24
|
+
# @yieldreturn [void]
|
25
|
+
# @raise [ArgumentError] if the XPath is +nil+.
|
26
|
+
def initialize(parent, context, **options, &block)
|
27
|
+
@child_node_by_context = {}
|
28
|
+
|
29
|
+
if context.nil?
|
30
|
+
raise ::ArgumentError
|
31
|
+
else
|
32
|
+
@context = context
|
33
|
+
end
|
34
|
+
|
35
|
+
super(parent, **options, &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Create a new +Nodes::Permit+ object.
|
39
|
+
#
|
40
|
+
# @param context [String] the XPath.
|
41
|
+
# @param options [Hash<Symbol, Object>] the options.
|
42
|
+
# @yieldparam node [Nokogiri::XML::Schematron::Nodes::Permit] the +Nodes::Permit+ object.
|
43
|
+
# @yieldreturn [void]
|
44
|
+
# @return [Nokogiri::XML::Schematron::Nodes::Permit] the +Nodes::Permit+ object.
|
45
|
+
# @raise [ArgumentError] if the XPath is +nil+.
|
46
|
+
def permit(context, **options, &block)
|
47
|
+
node = Nokogiri::XML::Schematron::Nodes::Permit.new(self, context, **options, &block)
|
48
|
+
@child_node_by_context[context] = node
|
49
|
+
node
|
50
|
+
end
|
51
|
+
|
52
|
+
# Create a new +Nodes::Reject+ object.
|
53
|
+
#
|
54
|
+
# @param context [String] the XPath.
|
55
|
+
# @param options [Hash<Symbol, Object>] the options.
|
56
|
+
# @yieldparam node [Nokogiri::XML::Schematron::Nodes::Reject] the +Nodes::Reject+ object.
|
57
|
+
# @yieldreturn [void]
|
58
|
+
# @return [Nokogiri::XML::Schematron::Nodes::Reject] the +Nodes::Reject+ object.
|
59
|
+
# @raise [ArgumentError] if the XPath is +nil+.
|
60
|
+
def reject(context, **options, &block)
|
61
|
+
node = Nokogiri::XML::Schematron::Nodes::Reject.new(self, context, **options, &block)
|
62
|
+
@child_node_by_context[context] = node
|
63
|
+
node
|
64
|
+
end
|
65
|
+
|
66
|
+
# Create a new +Nodes::Require+ object.
|
67
|
+
#
|
68
|
+
# @param context [String] the XPath.
|
69
|
+
# @param options [Hash<Symbol, Object>] the options.
|
70
|
+
# @yieldparam node [Nokogiri::XML::Schematron::Nodes::Require] the +Nodes::Require+ object.
|
71
|
+
# @yieldreturn [void]
|
72
|
+
# @return [Nokogiri::XML::Schematron::Nodes::Require] the +Nodes::Require+ object.
|
73
|
+
# @raise [ArgumentError] if the XPath is +nil+.
|
74
|
+
def require(context, **options, &block)
|
75
|
+
node = Nokogiri::XML::Schematron::Nodes::Require.new(self, context, **options, &block)
|
76
|
+
@child_node_by_context[context] = node
|
77
|
+
node
|
78
|
+
end
|
79
|
+
|
80
|
+
# Create a new +Nodes::Validations::Exclusion+ object.
|
81
|
+
#
|
82
|
+
# @param context [String] the XPath.
|
83
|
+
# @param options [Hash<Symbol, Object>] the options.
|
84
|
+
# @option options [Array<String>] :in ([]) the array of available items.
|
85
|
+
# @yieldparam node [Nokogiri::XML::Schematron::Nodes::Validations::Exclusion] the +Nodes::Validations::Exclusion+ object.
|
86
|
+
# @yieldreturn [void]
|
87
|
+
# @return [Nokogiri::XML::Schematron::Nodes::Validations::Exclusion] the +Nodes::Validations::Exclusion+ object.
|
88
|
+
def validates_exclusion_of(context, **options, &block)
|
89
|
+
node = Nokogiri::XML::Schematron::Nodes::Validations::Exclusion.new(self, context, **options, &block)
|
90
|
+
@child_node_by_context[context] = node
|
91
|
+
node
|
92
|
+
end
|
93
|
+
|
94
|
+
# Create a new +Nodes::Validations::Inclusion+ object.
|
95
|
+
#
|
96
|
+
# @param context [String] the XPath.
|
97
|
+
# @param options [Hash<Symbol, Object>] the options.
|
98
|
+
# @option options [Array<String>] :in ([]) the array of available items.
|
99
|
+
# @yieldparam node [Nokogiri::XML::Schematron::Nodes::Validations::Inclusion] the +Nodes::Validations::Inclusion+ object.
|
100
|
+
# @yieldreturn [void]
|
101
|
+
# @return [Nokogiri::XML::Schematron::Nodes::Validations::Inclusion] the +Nodes::Validations::Inclusion+ object.
|
102
|
+
def validates_inclusion_of(context, **options, &block)
|
103
|
+
node = Nokogiri::XML::Schematron::Nodes::Validations::Inclusion.new(self, context, **options, &block)
|
104
|
+
@child_node_by_context[context] = node
|
105
|
+
node
|
106
|
+
end
|
107
|
+
|
108
|
+
# Create a new +Nodes::Validations::Numericality+ object.
|
109
|
+
#
|
110
|
+
# @param context [String] the XPath.
|
111
|
+
# @param options [Hash<Symbol, Object>] the options.
|
112
|
+
# @option options [Boolean] :even (false) Specifies the value must be an even number.
|
113
|
+
# @option options [Integer, Float] :equal_to (nil) Specifies the value must be equal to the supplied value.
|
114
|
+
# @option options [Integer, Float] :greater_than (nil) Specifies the value must be greater than the supplied value.
|
115
|
+
# @option options [Integer, Float] :greater_than_or_equal_to (nil) Specifies the value must be greater than or equal the supplied value.
|
116
|
+
# @option options [Integer, Float] :less_than (nil) Specifies the value must be less than the supplied value.
|
117
|
+
# @option options [Integer, Float] :less_than_or_equal_to (nil) Specifies the value must be less than or equal the supplied value.
|
118
|
+
# @option options [Boolean] :odd (false) Specifies the value must be an odd number.
|
119
|
+
# @option options [Integer, Float] :other_than (nil) Specifies the value must be other than the supplied value.
|
120
|
+
# @yieldparam node [Nokogiri::XML::Schematron::Nodes::Validations::Numericality] the +Nodes::Validations::Numericality+ object.
|
121
|
+
# @yieldreturn [void]
|
122
|
+
# @return [Nokogiri::XML::Schematron::Nodes::Validations::Numericality] the +Nodes::Validations::Numericality+ object.
|
123
|
+
def validates_numericality_of(context, **options, &block)
|
124
|
+
node = Nokogiri::XML::Schematron::Nodes::Validations::Numericality.new(self, context, **options, &block)
|
125
|
+
@child_node_by_context[context] = node
|
126
|
+
node
|
127
|
+
end
|
128
|
+
|
129
|
+
protected
|
130
|
+
|
131
|
+
def build!(xml)
|
132
|
+
if @child_node_by_context.any?
|
133
|
+
xml["sch"].send(:rule, xmlns.merge({
|
134
|
+
"context" => send(:absolute_context),
|
135
|
+
})) do
|
136
|
+
@child_node_by_context.each_pair.sort_by { |pair| pair[0] }.each do |pair|
|
137
|
+
pair[1].send(:build_assertion!, xml)
|
138
|
+
end
|
139
|
+
|
140
|
+
super(xml)
|
141
|
+
end
|
142
|
+
|
143
|
+
@child_node_by_context.each_pair.sort_by { |pair| pair[0] }.each do |pair|
|
144
|
+
pair[1].send(:build!, xml)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
return
|
149
|
+
end
|
150
|
+
|
151
|
+
# Build the XML representation of the +<sch:assert>+ XML element.
|
152
|
+
#
|
153
|
+
# @param xml [Nokogiri::XML::Builder] the XML builder.
|
154
|
+
# @return [void]
|
155
|
+
def build_assertion!(xml)
|
156
|
+
return
|
157
|
+
end
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
# @return [String] the absolute XPath with respect to the abstract syntax tree.
|
162
|
+
def absolute_context
|
163
|
+
return @context unless @parent.is_a?(Nokogiri::XML::Schematron::Nodes::Base)
|
164
|
+
|
165
|
+
prefix = @parent.send(:absolute_context)
|
166
|
+
|
167
|
+
separator = \
|
168
|
+
case prefix
|
169
|
+
when "/" then ""
|
170
|
+
else "/"
|
171
|
+
end
|
172
|
+
|
173
|
+
[
|
174
|
+
prefix,
|
175
|
+
@context,
|
176
|
+
].join(separator)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
require "nokogiri/xml/schematron/nodes/permit"
|
185
|
+
require "nokogiri/xml/schematron/nodes/reject"
|
186
|
+
require "nokogiri/xml/schematron/nodes/require"
|
187
|
+
require "nokogiri/xml/schematron/nodes/validations/exclusion"
|
188
|
+
require "nokogiri/xml/schematron/nodes/validations/inclusion"
|
189
|
+
require "nokogiri/xml/schematron/nodes/validations/numericality"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "nokogiri/xml/schematron/nodes/base"
|
2
|
+
|
3
|
+
module Nokogiri
|
4
|
+
module XML
|
5
|
+
module Schematron
|
6
|
+
module Nodes
|
7
|
+
# The abstract syntax tree node whose +@context+ XML attribute is the root.
|
8
|
+
class Context < Nokogiri::XML::Schematron::Nodes::Base
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "nokogiri/xml/schematron/nodes/base"
|
2
|
+
|
3
|
+
module Nokogiri
|
4
|
+
module XML
|
5
|
+
module Schematron
|
6
|
+
module Nodes
|
7
|
+
# The abstract syntax tree node whose +@context+ XML attribute is OPTIONAL.
|
8
|
+
class Permit < Nokogiri::XML::Schematron::Nodes::Base
|
9
|
+
protected
|
10
|
+
|
11
|
+
def build_assertion!(xml)
|
12
|
+
xml["sch"].send(:assert, xmlns.merge({
|
13
|
+
"test" => "count(#{@context}) >= 0",
|
14
|
+
})) do
|
15
|
+
xml.text("element \"#{@context}\" is OPTIONAL")
|
16
|
+
end
|
17
|
+
|
18
|
+
return
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "nokogiri/xml/schematron/nodes/base"
|
2
|
+
|
3
|
+
module Nokogiri
|
4
|
+
module XML
|
5
|
+
module Schematron
|
6
|
+
module Nodes
|
7
|
+
# The abstract syntax tree node whose +@context+ XML attribute is NOT RECOMMENDED.
|
8
|
+
class Reject < Nokogiri::XML::Schematron::Nodes::Base
|
9
|
+
protected
|
10
|
+
|
11
|
+
def build_assertion!(xml)
|
12
|
+
xml["sch"].send(:assert, xmlns.merge({
|
13
|
+
"test" => "not(#{@context})",
|
14
|
+
})) do
|
15
|
+
xml.text("element \"#{@context}\" is NOT RECOMMENDED")
|
16
|
+
end
|
17
|
+
|
18
|
+
return
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "nokogiri/xml/schematron/nodes/base"
|
2
|
+
|
3
|
+
module Nokogiri
|
4
|
+
module XML
|
5
|
+
module Schematron
|
6
|
+
module Nodes
|
7
|
+
# The abstract syntax tree node whose +@context+ XML attribute is REQUIRED.
|
8
|
+
class Require < Nokogiri::XML::Schematron::Nodes::Base
|
9
|
+
protected
|
10
|
+
|
11
|
+
def build_assertion!(xml)
|
12
|
+
xml["sch"].send(:assert, xmlns.merge({
|
13
|
+
"test" => "count(#{@context}) >= 1",
|
14
|
+
})) do
|
15
|
+
xml.text("element \"#{@context}\" is REQUIRED")
|
16
|
+
end
|
17
|
+
|
18
|
+
return
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "nokogiri/xml/schematron/internal/core_ext/array"
|
2
|
+
require "nokogiri/xml/schematron/nodes/base"
|
3
|
+
|
4
|
+
module Nokogiri
|
5
|
+
module XML
|
6
|
+
module Schematron
|
7
|
+
module Nodes
|
8
|
+
module Validations
|
9
|
+
# The abstract syntax tree node that uses the +contains(haystack, needle)+
|
10
|
+
# XPath function, where +haystack+ and +needle+ are strings, to test
|
11
|
+
# if the +@context+ XML attribute is not included in an array of
|
12
|
+
# available items.
|
13
|
+
#
|
14
|
+
# For the supplied array of available items
|
15
|
+
#
|
16
|
+
# ["a", "b", "c"]
|
17
|
+
#
|
18
|
+
# and context
|
19
|
+
#
|
20
|
+
# "/x/y/z/text()"
|
21
|
+
#
|
22
|
+
# this abstract syntax tree node is equivalent to the XPath:
|
23
|
+
#
|
24
|
+
# "not(contains('_a_ _b_ _c_', concat('_', /x/y/z/text(), '_')))"
|
25
|
+
#
|
26
|
+
class Exclusion < Nokogiri::XML::Schematron::Nodes::Base
|
27
|
+
# @!attribute [rw] in
|
28
|
+
# @return [Array<String>] the array of available items.
|
29
|
+
attribute :in
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def build_assertion!(xml)
|
34
|
+
xml["sch"].send(:assert, xmlns.merge({
|
35
|
+
"test" => "not(contains('#{(send(:in) || []).collect { |s| "_#{s.gsub("'", "\\'")}_" }.join(" ")}', concat('_', #{@context}, '_')))",
|
36
|
+
})) do
|
37
|
+
xml.text("text \"")
|
38
|
+
xml["sch"].send(:"value-of", {
|
39
|
+
"select" => @context,
|
40
|
+
})
|
41
|
+
xml.text("\": element \"#{@context}\" MUST NOT be #{Nokogiri::XML::Schematron::Internal::CoreExt::Array.to_sentence((send(:in) || []).collect { |s| "\"#{s.gsub("\"", "\\\"")}\"" }, last_word_connector: ", or ", two_words_connector: " or ", words_connector: ", ")}")
|
42
|
+
end
|
43
|
+
|
44
|
+
return
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "nokogiri/xml/schematron/internal/core_ext/array"
|
2
|
+
require "nokogiri/xml/schematron/nodes/base"
|
3
|
+
|
4
|
+
module Nokogiri
|
5
|
+
module XML
|
6
|
+
module Schematron
|
7
|
+
module Nodes
|
8
|
+
module Validations
|
9
|
+
# The abstract syntax tree node that uses the +contains(haystack, needle)+
|
10
|
+
# XPath function, where +haystack+ and +needle+ are strings, to test
|
11
|
+
# if the +@context+ XML attribute is included in an array of available
|
12
|
+
# items.
|
13
|
+
#
|
14
|
+
# For the supplied array of available items
|
15
|
+
#
|
16
|
+
# ["a", "b", "c"]
|
17
|
+
#
|
18
|
+
# and context
|
19
|
+
#
|
20
|
+
# "/x/y/z/text()"
|
21
|
+
#
|
22
|
+
# this abstract syntax tree node is equivalent to the XPath:
|
23
|
+
#
|
24
|
+
# "contains('_a_ _b_ _c_', concat('_', /x/y/z/text(), '_'))"
|
25
|
+
#
|
26
|
+
class Inclusion < Nokogiri::XML::Schematron::Nodes::Base
|
27
|
+
# @!attribute [rw] in
|
28
|
+
# @return [Array<String>] the array of available items.
|
29
|
+
attribute :in
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def build_assertion!(xml)
|
34
|
+
xml["sch"].send(:assert, xmlns.merge({
|
35
|
+
"test" => "contains('#{(send(:in) || []).collect { |s| "_#{s.gsub("'", "\\'")}_" }.join(" ")}', concat('_', #{@context}, '_'))",
|
36
|
+
})) do
|
37
|
+
xml.text("text \"")
|
38
|
+
xml["sch"].send(:"value-of", {
|
39
|
+
"select" => @context,
|
40
|
+
})
|
41
|
+
xml.text("\": element \"#{@context}\" MUST be #{Nokogiri::XML::Schematron::Internal::CoreExt::Array.to_sentence((send(:in) || []).collect { |s| "\"#{s.gsub("\"", "\\\"")}\"" }, last_word_connector: ", or ", two_words_connector: " or ", words_connector: ", ")}")
|
42
|
+
end
|
43
|
+
|
44
|
+
return
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require "nokogiri/xml/schematron/internal/core_ext/array"
|
2
|
+
require "nokogiri/xml/schematron/nodes/base"
|
3
|
+
|
4
|
+
module Nokogiri
|
5
|
+
module XML
|
6
|
+
module Schematron
|
7
|
+
module Nodes
|
8
|
+
module Validations
|
9
|
+
# The abstract syntax tree node that uses the +number(any)+
|
10
|
+
# XPath function, where +any+ is any value, to test if the +@context+
|
11
|
+
# XML attribute is numeric.
|
12
|
+
class Numericality < Nokogiri::XML::Schematron::Nodes::Base
|
13
|
+
# @!attribute [rw] even
|
14
|
+
# @return [Boolean] the value must be an even number.
|
15
|
+
attribute :even
|
16
|
+
|
17
|
+
# @!attribute [rw] equal_to
|
18
|
+
# @return [Integer, Float] the value must be equal to the supplied value.
|
19
|
+
attribute :equal_to
|
20
|
+
|
21
|
+
# @!attribute [rw] greater_than
|
22
|
+
# @return [Integer, Float] the value must be greater than the supplied value.
|
23
|
+
attribute :greater_than
|
24
|
+
|
25
|
+
# @!attribute [rw] greater_than_or_equal_to
|
26
|
+
# @return [Integer, Float] the value must be greater than or equal the supplied value.
|
27
|
+
attribute :greater_than_or_equal_to
|
28
|
+
|
29
|
+
# @!attribute [rw] less_than
|
30
|
+
# @return [Integer, Float] the value must be less than the supplied value.
|
31
|
+
attribute :less_than
|
32
|
+
|
33
|
+
# @!attribute [rw] less_than_or_equal_to
|
34
|
+
# @return [Integer, Float] the value must be less than or equal the supplied value.
|
35
|
+
attribute :less_than_or_equal_to
|
36
|
+
|
37
|
+
# @!attribute [rw] odd
|
38
|
+
# @return [Boolean] the value must be an odd number.
|
39
|
+
attribute :odd
|
40
|
+
|
41
|
+
# @!attribute [rw] other_than
|
42
|
+
# @return [Integer, Float] the value must be other than the supplied value.
|
43
|
+
attribute :other_than
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
def build_assertion!(xml)
|
48
|
+
tests = [
|
49
|
+
"number(#{@context}) = #{@context}",
|
50
|
+
]
|
51
|
+
|
52
|
+
messages = [
|
53
|
+
"MUST be a number",
|
54
|
+
]
|
55
|
+
|
56
|
+
PROC_BY_METHOD_NAME.each do |method_name, block|
|
57
|
+
unless (orig_value = send(method_name.to_sym)).nil? || (pair = block.call(orig_value)).nil?
|
58
|
+
tests << pair[0]
|
59
|
+
messages << pair[1]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
xml["sch"].send(:assert, xmlns.merge({
|
64
|
+
"test" => tests.collect { |s| "(#{s})" }.join(" and "),
|
65
|
+
})) do
|
66
|
+
xml.text("text \"")
|
67
|
+
xml["sch"].send(:"value-of", {
|
68
|
+
"select" => @context,
|
69
|
+
})
|
70
|
+
xml.text("\": element \"#{@context}\" #{Nokogiri::XML::Schematron::Internal::CoreExt::Array.to_sentence(messages, last_word_connector: ", and ", two_words_connector: " and ", words_connector: ", ")}")
|
71
|
+
end
|
72
|
+
|
73
|
+
return
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
# @return [Hash<Symbol, Proc>] the hash of blocks by method name.
|
79
|
+
PROC_BY_METHOD_NAME = {
|
80
|
+
even: ::Proc.new { |bool|
|
81
|
+
if bool == true
|
82
|
+
[
|
83
|
+
"number(#{@context}) mod 2 = 0",
|
84
|
+
"MUST be even",
|
85
|
+
]
|
86
|
+
else
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
},
|
90
|
+
equal_to: ::Proc.new { |number|
|
91
|
+
[
|
92
|
+
"number(#{@context}) = #{number}",
|
93
|
+
"MUST be equal to #{number}",
|
94
|
+
]
|
95
|
+
},
|
96
|
+
greater_than: ::Proc.new { |number|
|
97
|
+
[
|
98
|
+
"number(#{@context}) > #{number}",
|
99
|
+
"MUST be greater than #{number}",
|
100
|
+
]
|
101
|
+
},
|
102
|
+
greater_than_or_equal_to: ::Proc.new { |number|
|
103
|
+
[
|
104
|
+
"number(#{@context}) >= #{number}",
|
105
|
+
"MUST be greater than or equal to #{number}",
|
106
|
+
]
|
107
|
+
},
|
108
|
+
less_than: ::Proc.new { |number|
|
109
|
+
[
|
110
|
+
"number(#{@context}) < #{number}",
|
111
|
+
"MUST be less than #{number}",
|
112
|
+
]
|
113
|
+
},
|
114
|
+
less_than_or_equal_to: ::Proc.new { |number|
|
115
|
+
[
|
116
|
+
"number(#{@context}) <= #{number}",
|
117
|
+
"MUST be less than or equal to #{number}",
|
118
|
+
]
|
119
|
+
},
|
120
|
+
odd: ::Proc.new { |bool|
|
121
|
+
if bool == true
|
122
|
+
[
|
123
|
+
"number(#{@context}) mod 2 = 1",
|
124
|
+
"MUST be odd",
|
125
|
+
]
|
126
|
+
else
|
127
|
+
nil
|
128
|
+
end
|
129
|
+
},
|
130
|
+
other_than: ::Proc.new { |number|
|
131
|
+
[
|
132
|
+
"number(#{@context}) != #{number}",
|
133
|
+
"MUST NOT be equal to #{number}",
|
134
|
+
]
|
135
|
+
},
|
136
|
+
}
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|