xsd 1.0.0 → 2.0.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.
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: