xsd 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/Gemfile +9 -0
  4. data/README.md +3 -2
  5. data/lib/xsd/base_object.rb +35 -35
  6. data/lib/xsd/generator.rb +7 -7
  7. data/lib/xsd/objects/all.rb +2 -2
  8. data/lib/xsd/objects/annotation.rb +2 -2
  9. data/lib/xsd/objects/any.rb +2 -2
  10. data/lib/xsd/objects/any_attribute.rb +2 -2
  11. data/lib/xsd/objects/appinfo.rb +1 -1
  12. data/lib/xsd/objects/attribute.rb +9 -9
  13. data/lib/xsd/objects/attribute_group.rb +1 -1
  14. data/lib/xsd/objects/choice.rb +4 -4
  15. data/lib/xsd/objects/complex_content.rb +3 -3
  16. data/lib/xsd/objects/complex_type.rb +12 -12
  17. data/lib/xsd/objects/documentation.rb +2 -2
  18. data/lib/xsd/objects/element.rb +19 -19
  19. data/lib/xsd/objects/facet.rb +1 -1
  20. data/lib/xsd/objects/field.rb +1 -1
  21. data/lib/xsd/objects/group.rb +4 -4
  22. data/lib/xsd/objects/import.rb +15 -44
  23. data/lib/xsd/objects/key.rb +3 -3
  24. data/lib/xsd/objects/keyref.rb +4 -4
  25. data/lib/xsd/objects/list.rb +1 -1
  26. data/lib/xsd/objects/restriction.rb +3 -3
  27. data/lib/xsd/objects/schema.rb +31 -31
  28. data/lib/xsd/objects/selector.rb +1 -1
  29. data/lib/xsd/objects/sequence.rb +4 -4
  30. data/lib/xsd/objects/simple_content.rb +2 -2
  31. data/lib/xsd/objects/simple_type.rb +5 -5
  32. data/lib/xsd/objects/union.rb +2 -2
  33. data/lib/xsd/objects/unique.rb +2 -2
  34. data/lib/xsd/shared/attribute_container.rb +2 -2
  35. data/lib/xsd/shared/based.rb +9 -9
  36. data/lib/xsd/shared/complex_typed.rb +7 -7
  37. data/lib/xsd/shared/element_container.rb +1 -1
  38. data/lib/xsd/shared/min_max_occurs.rb +4 -4
  39. data/lib/xsd/shared/referenced.rb +3 -3
  40. data/lib/xsd/shared/simple_typed.rb +1 -1
  41. data/lib/xsd/validator.rb +1 -1
  42. data/lib/xsd/version.rb +1 -1
  43. data/lib/xsd/xml.rb +102 -31
  44. data/xsd.gemspec +0 -8
  45. metadata +2 -100
@@ -5,15 +5,15 @@ module XSD
5
5
  module Based
6
6
  # Required. Specifies the name of a built-in data type, a simpleType element, or a complexType element
7
7
  # @!attribute base
8
- # @return [String]
8
+ # @return String
9
9
 
10
10
  # Base complexType
11
11
  # @!attribute base_complex_type
12
- # @return [ComplexType, nil]
12
+ # @return ComplexType, nil
13
13
 
14
14
  # Base simpleType
15
15
  # @!attribute base_simple_type
16
- # @return [SimpleType, nil]
16
+ # @return SimpleType, nil
17
17
  def self.included(obj)
18
18
  obj.property :base, :string, required: true
19
19
  obj.link :base_complex_type, :complexType, property: :base
@@ -22,16 +22,16 @@ module XSD
22
22
 
23
23
  # Get all available elements on the current stack level, optionally including base type elements
24
24
  # @param [Boolean] include_base
25
- # @return [Array<Element>]
26
- def all_elements(include_base = true)
27
- (include_base && base_complex_type ? base_complex_type.all_elements : []) + super
25
+ # @return Array<Element>
26
+ def collect_elements(include_base = true)
27
+ (include_base && base_complex_type ? base_complex_type.collect_elements : []) + super
28
28
  end
29
29
 
30
30
  # Get all available attributes on the current stack level, optionally including base type attributes
31
31
  # @param [Boolean] include_base
32
- # @return [Array<Attribute>]
33
- def all_attributes(include_base = true)
34
- (include_base && base_complex_type ? base_complex_type.all_attributes : []) + super
32
+ # @return Array<Attribute>
33
+ def collect_attributes(include_base = true)
34
+ (include_base && base_complex_type ? base_complex_type.collect_attributes : []) + super
35
35
  end
36
36
  end
37
37
  end
@@ -5,7 +5,7 @@ module XSD
5
5
  module ComplexTyped
6
6
  # Child/linked complex type
7
7
  # @!attribute complex_type
8
- # @return [ComplexType, nil]
8
+ # @return ComplexType, nil
9
9
  def self.included(obj)
10
10
  obj.child :complex_type, :complexType
11
11
  obj.link :complex_type, :complexType, property: obj::TYPE_PROPERTY
@@ -13,16 +13,16 @@ module XSD
13
13
 
14
14
  # Get all available elements on the current stack level or linked type elements
15
15
  # @param [Boolean] linked_type
16
- # @return [Array<Element>]
17
- def all_elements(linked_type = true)
18
- (linked_type && complex_type&.linked? ? complex_type.all_elements : super)
16
+ # @return Array<Element>
17
+ def collect_elements(linked_type = true)
18
+ (linked_type && complex_type&.linked? ? complex_type.collect_elements : super)
19
19
  end
20
20
 
21
21
  # Get all available attributes on the current stack level or linked type attributes
22
22
  # @param [Boolean] linked_type
23
- # @return [Array<Attribute>]
24
- def all_attributes(linked_type = true)
25
- (linked_type && complex_type&.linked? ? complex_type.all_attributes : super)
23
+ # @return Array<Attribute>
24
+ def collect_attributes(linked_type = true)
25
+ (linked_type && complex_type&.linked? ? complex_type.collect_attributes : super)
26
26
  end
27
27
  end
28
28
  end
@@ -4,7 +4,7 @@ module XSD
4
4
  module ElementContainer
5
5
  # Nested elements
6
6
  # @!attribute elements
7
- # @return [Array<Element>]
7
+ # @return Array<Element>
8
8
  def self.included(obj)
9
9
  obj.child :elements, [:element]
10
10
  end
@@ -5,20 +5,20 @@ module XSD
5
5
  # Optional. Specifies the minimum number of times the choice element can occur in the parent the element.
6
6
  # The value can be any number >= 0. Default value is 1
7
7
  # @!attribute min_occurs
8
- # @return [Integer]
8
+ # @return Integer
9
9
 
10
10
  # Optional. Specifies the maximum number of times the choice element can occur in the parent element.
11
11
  # The value can be any number >= 0, or if you want to set no limit on the maximum number, use the value "unbounded".
12
12
  # Default value is 1
13
13
  # @!attribute max_occurs
14
- # @return [Integer, Symbol]
14
+ # @return Integer, Symbol
15
15
  def self.included(obj)
16
16
  obj.property :minOccurs, :integer, default: 1
17
17
  obj.property :maxOccurs, :integer, default: 1
18
18
  end
19
19
 
20
20
  # Compute actual max_occurs accounting parents
21
- # @return [Integer, Symbol]
21
+ # @return Integer, Symbol
22
22
  def computed_max_occurs
23
23
  @computed_max_occurs ||= if parent.is_a?(MinMaxOccurs)
24
24
  if max_occurs == :unbounded || parent.computed_max_occurs == :unbounded
@@ -32,7 +32,7 @@ module XSD
32
32
  end
33
33
 
34
34
  # Compute actual min_occurs accounting parents
35
- # @return [Integer]
35
+ # @return Integer
36
36
  def computed_min_occurs
37
37
  @computed_min_occurs ||= if parent.is_a?(Choice)
38
38
  0
@@ -5,18 +5,18 @@ module XSD
5
5
  # Optional. Specifies a reference to a named attribute. Name and ref attributes cannot both be present.
6
6
  # If ref is present, simpleType element, form, and type cannot be present
7
7
  # @!attribute ref
8
- # @return [String]
8
+ # @return String
9
9
 
10
10
  # Reference object
11
11
  # @!attribute reference
12
- # @return [BaseObject]
12
+ # @return BaseObject
13
13
  def self.included(obj)
14
14
  obj.property :ref, :string
15
15
  obj.link :reference, obj.mapped_name, property: :ref
16
16
  end
17
17
 
18
18
  # Is object referenced?
19
- # @return [Boolean]
19
+ # @return Boolean
20
20
  def referenced?
21
21
  !ref.nil?
22
22
  end
@@ -5,7 +5,7 @@ module XSD
5
5
  module SimpleTyped
6
6
  # Get child/linked simple type
7
7
  # @!attribute simple_type
8
- # @return [SimpleType, nil]
8
+ # @return SimpleType, nil
9
9
  def self.included(obj)
10
10
  obj.child :simple_type, :simpleType
11
11
  obj.link :simple_type, :simpleType, property: obj::TYPE_PROPERTY
data/lib/xsd/validator.rb CHANGED
@@ -32,7 +32,7 @@ module XSD
32
32
  private
33
33
 
34
34
  # Get Nokogiri::XML::Schema object to validate against
35
- # @return [Nokogiri::XML::Schema]
35
+ # @return Nokogiri::XML::Schema
36
36
  def schema_validator
37
37
  return @schema_validator if @schema_validator
38
38
 
data/lib/xsd/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module XSD
4
- VERSION = '1.0.0'
4
+ VERSION = '2.0.0'
5
5
  end
data/lib/xsd/xml.rb CHANGED
@@ -1,19 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'nokogiri'
4
- require 'forwardable'
4
+ require 'net/http'
5
5
 
6
6
  module XSD
7
7
  class XML
8
- extend Forwardable
9
8
  include Generator
10
9
  include Validator
11
10
 
12
- attr_reader :options, :object_cache, :xsd
11
+ attr_reader :options, :object_cache, :schemas, :namespace_prefixes
13
12
 
14
- # Proxy lookup methods to schema
15
- def_delegators :schema, :[], :elements, :all_elements, :attributes, :attribute_groups, :all_attributes,
16
- :complex_types, :simple_types, :groups, :imports
13
+ DEFAULT_RESOURCE_RESOLVER = proc do |location, namespace|
14
+ if location =~ /^https?:/
15
+ Net::HTTP.get(URI(location))
16
+ elsif Pathname.new(location).absolute?
17
+ File.read(location)
18
+ else
19
+ raise ImportError, "Failed to locate import '#{location}'#{namespace ? " for namespace '#{namespace}'" : ''}"
20
+ end
21
+ end
17
22
 
18
23
  CLASS_MAP = {
19
24
  'schema' => Schema,
@@ -58,54 +63,120 @@ module XSD
58
63
  'pattern' => Facet
59
64
  }.freeze
60
65
 
61
- def initialize(xsd, **options)
62
- # Base input validation
63
- raise Error, 'xsd is not a Pathname nor a string' unless xsd.is_a?(Pathname) || xsd.is_a?(String)
64
- raise Error, 'options is not a hash' unless options.is_a?(Hash)
66
+ def self.open(path, **options)
67
+ reader = new(**options)
68
+ reader.add_schema_xml(File.read(path))
69
+ reader
70
+ end
65
71
 
66
- @xsd = xsd
67
- @options = options
68
- @object_cache = {}
72
+ def initialize(**options)
73
+ @options = options
74
+ @object_cache = {}
75
+ @schemas = []
76
+ @namespace_prefixes = {}
69
77
  end
70
78
 
71
79
  def logger
72
80
  options[:logger] || default_logger
73
81
  end
74
82
 
75
- def default_logger
76
- @default_logger ||= Logger.new($stdout).tap do |logger|
77
- logger.level = Logger::WARN
83
+ def resource_resolver
84
+ @options[:resource_resolver] || DEFAULT_RESOURCE_RESOLVER
85
+ end
86
+
87
+ def tmp_dir
88
+ @tmp_dir ||= options[:tmp_dir]
89
+ end
90
+
91
+ def read_document(xml)
92
+ Nokogiri::XML(xml)
93
+ end
94
+
95
+ # Get imported schema
96
+ # @return XSD:Schema
97
+ def add_schema_xml(xml)
98
+ doc = read_document(xml)
99
+ raise Error, 'Schema node not found, xml does not seem to be a valid XSD' unless doc.root&.name == 'schema'
100
+
101
+ add_schema_node(doc.root)
102
+ end
103
+
104
+ # Get imported schema
105
+ # @return Schema
106
+ def add_schema_node(node)
107
+ raise Error, 'Added schema must be of type Nokogiri::XML::Node' unless node.is_a?(Nokogiri::XML::Node)
108
+
109
+ schema = Schema.new(self.options.merge(node: node, reader: self))
110
+ schemas.push(schema)
111
+
112
+ schema
113
+ end
114
+
115
+ # Add prefixes defined outside of processed schemas, for example in WSDL document
116
+ # @param [String] prefix
117
+ # @param [String] namespace
118
+ def add_namespace_prefix(prefix, namespace)
119
+ @namespace_prefixes[prefix] = namespace
120
+ end
121
+
122
+ # Get first added (considered primary) schema
123
+ # @return Schema, nil
124
+ def schema
125
+ schemas.first
126
+ end
127
+
128
+ # Get schema by namespace or namespace prefix
129
+ # @return Schema, nil
130
+ def schema_for_namespace(namespace)
131
+ namespace = namespace_prefixes[namespace] if namespace_prefixes.key?(namespace)
132
+ schemas.find { |schema| schema.target_namespace == namespace }
133
+ end
134
+
135
+ def [](*args)
136
+ schemas.each do |schema|
137
+ item = schema[*args]
138
+ return item if item
78
139
  end
140
+
141
+ nil
79
142
  end
80
143
 
81
- def xml
82
- @xsd_xml ||= xsd.is_a?(Pathname) ? File.read(xsd) : xsd
144
+ def elements(*args)
145
+ collect(:elements, *args)
83
146
  end
84
147
 
85
- def imported_xsd
86
- @imported_xsd ||= options[:imported_xsd] || {}
148
+ def attributes(*args)
149
+ collect(:attributes, *args)
87
150
  end
88
151
 
89
- def tmp_dir
90
- @tmp_dir ||= options[:tmp_dir]
152
+ def attribute_groups
153
+ collect(:attribute_groups)
91
154
  end
92
155
 
93
- def doc
94
- @doc ||= Nokogiri::XML(xml)
156
+ def complex_types
157
+ collect(:complex_types)
95
158
  end
96
159
 
97
- def schema_node
98
- raise Error, 'Document root not found, provided document does not seem to be a valid XSD' unless doc.root
160
+ def simple_types
161
+ collect(:simple_types)
162
+ end
99
163
 
100
- doc.root.name == 'schema' ? doc.root : nil
164
+ def groups
165
+ collect(:groups)
101
166
  end
102
167
 
103
- def schema
104
- @schema ||= Schema.new(self.options.merge(node: schema_node, reader: self))
168
+ private
169
+
170
+ def collect(name, *args)
171
+ result = Set.new
172
+ schemas.each { |schema| result.merge(schema.send(name, *args)) }
173
+ result.to_a
105
174
  end
106
175
 
107
- def schema_for_namespace(_ns)
108
- schema.schema_for_namespace(_ns)
176
+ def default_logger
177
+ @default_logger ||= Logger.new($stdout).tap do |logger|
178
+ logger.level = Logger::WARN
179
+ end
109
180
  end
110
181
  end
111
182
  end
data/xsd.gemspec CHANGED
@@ -34,12 +34,4 @@ Gem::Specification.new do |spec|
34
34
  spec.add_dependency 'builder', '~> 3.2'
35
35
  spec.add_dependency 'nokogiri', '~> 1.11'
36
36
  spec.add_dependency 'rake', '~> 13.0'
37
- spec.add_dependency 'rest-client', '~> 2.1'
38
-
39
- spec.add_development_dependency 'logger', '~> 1.5'
40
- spec.add_development_dependency 'rspec', '~> 3.12'
41
- spec.add_development_dependency 'rubocop', '~> 1.50'
42
- spec.add_development_dependency 'rubocop-performance', '~> 1.17'
43
- spec.add_development_dependency 'rubocop-rake', '~> 0.6'
44
- spec.add_development_dependency 'rubocop-rspec', '~> 2.10'
45
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xsd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - d.arkhipov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-27 00:00:00.000000000 Z
11
+ date: 2023-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: builder
@@ -52,104 +52,6 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '13.0'
55
- - !ruby/object:Gem::Dependency
56
- name: rest-client
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '2.1'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '2.1'
69
- - !ruby/object:Gem::Dependency
70
- name: logger
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '1.5'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '1.5'
83
- - !ruby/object:Gem::Dependency
84
- name: rspec
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '3.12'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '3.12'
97
- - !ruby/object:Gem::Dependency
98
- name: rubocop
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '1.50'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '1.50'
111
- - !ruby/object:Gem::Dependency
112
- name: rubocop-performance
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '1.17'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '1.17'
125
- - !ruby/object:Gem::Dependency
126
- name: rubocop-rake
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '0.6'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '0.6'
139
- - !ruby/object:Gem::Dependency
140
- name: rubocop-rspec
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '2.10'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: '2.10'
153
55
  description: The Ruby XSD library is an XML Schema implementation for Ruby.Provides
154
56
  easy and flexible access to XSD information
155
57
  email: