xsd 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +11 -2
- data/lib/xsd/base_object.rb +13 -10
- data/lib/xsd/objects/extension.rb +20 -1
- data/lib/xsd/objects/import.rb +7 -7
- data/lib/xsd/objects/include.rb +29 -0
- data/lib/xsd/objects/restriction.rb +20 -0
- data/lib/xsd/objects/schema.rb +13 -7
- data/lib/xsd/version.rb +1 -1
- data/lib/xsd/xml.rb +15 -10
- data/lib/xsd.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3b12830c536c37e72b109727f470d45de29b6c852e62476cd3aa5578dd3b9c7
|
4
|
+
data.tar.gz: 248b65a3794a6c83a6aca695b0d565d55b971991272fd5f7f0a8a841fb8847ec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac15d2c2c163bd70f007fd76b5c007fbc786ed09d5609a2d6dba5aa8836144917a5159a32c1b7f47aa250bd18034d8339f445180fc4cd330745138ec60283e32
|
7
|
+
data.tar.gz: 7db0b9ac2ba0c97aab16d84db5145b4a8a18c901f3c24c8fd13a73b96a1998083a41cff38c3b0f7098dc53457b693e0ee5d3d941ceb1712f38a54924d32ce544
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [2.1.0] - 2023-07-10
|
4
|
+
|
5
|
+
- Add support for <xs:include> element
|
6
|
+
- Changed method "schema_for_namespace(namespace) -> XSD::Schema" signature to "schemas_for_namespace(namespace) -> Array<XSD::Schema>"
|
7
|
+
|
3
8
|
## [2.0.0] - 2023-07-07
|
4
9
|
|
5
10
|
- Change XSD::XML.new(file, **options) -> XSD::XML.open(file, **options)
|
data/README.md
CHANGED
@@ -28,20 +28,29 @@ require 'xsd'
|
|
28
28
|
# Load ruby-xsd
|
29
29
|
reader = XSD::XML.open('some.xsd')
|
30
30
|
|
31
|
+
# Get elements and their child elements
|
32
|
+
element = reader['NewReleaseMessage']
|
33
|
+
element.collect_elements.map(&:name) # => ['MessageHeader', 'UpdateIndicator', 'IsBackfill', 'CatalogTransfer', 'WorkList', 'CueSheetList', 'ResourceList', 'CollectionList', 'ReleaseList', 'DealList']
|
34
|
+
|
31
35
|
# Get attributes
|
32
36
|
attribute = reader['NewReleaseMessage']['@MessageSchemaVersionId']
|
33
37
|
|
34
|
-
# Get
|
38
|
+
# Get attribute information
|
35
39
|
attribute.name # => 'MessageSchemaVersionId'
|
36
40
|
attribute.type # => 'xs:string'
|
37
41
|
attribute.required? # => true
|
42
|
+
attribute.optional? # => false
|
43
|
+
attribute.prohibited? # => true
|
38
44
|
|
39
45
|
# Get element information
|
40
|
-
element = reader['NewReleaseMessage']['ResourceList']['SoundRecording']
|
46
|
+
element = reader['NewReleaseMessage']['ResourceList']['SoundRecording'] # => XSD::Element
|
41
47
|
element.min_occurs # => 0
|
42
48
|
element.max_occurs # => :unbounded
|
43
49
|
element.type # => 'ern:SoundRecording'
|
44
50
|
element.complex_type # => XSD::ComplexType
|
51
|
+
element.complex? # => true
|
52
|
+
element.multiple_allowed? # => true
|
53
|
+
element.required? # => false
|
45
54
|
```
|
46
55
|
|
47
56
|
## Development
|
data/lib/xsd/base_object.rb
CHANGED
@@ -67,13 +67,13 @@ module XSD
|
|
67
67
|
end
|
68
68
|
|
69
69
|
# Get schema by namespace or namespace prefix
|
70
|
-
# @param [String] namespace
|
71
|
-
# @return Schema
|
72
|
-
def
|
70
|
+
# @param [String, nil] namespace
|
71
|
+
# @return Array<Schema>
|
72
|
+
def schemas_for_namespace(namespace)
|
73
73
|
if schema.targets_namespace?(namespace)
|
74
|
-
schema
|
74
|
+
[schema, *schema.includes.map(&:imported_schema)]
|
75
75
|
elsif (import = schema.import_by_namespace(namespace))
|
76
|
-
import.imported_schema
|
76
|
+
[import.imported_schema]
|
77
77
|
else
|
78
78
|
raise Error, "Schema not found for namespace '#{namespace}' in '#{schema.id || schema.target_namespace}'"
|
79
79
|
end
|
@@ -112,12 +112,15 @@ module XSD
|
|
112
112
|
return nil if schema.namespace_prefix == name_prefix
|
113
113
|
|
114
114
|
# determine schema for namespace
|
115
|
-
|
115
|
+
search_schemas = schemas_for_namespace(name_prefix)
|
116
116
|
|
117
117
|
# find element in target schema
|
118
|
-
|
118
|
+
search_schemas.each do |s|
|
119
|
+
node = s.node.xpath("./xs:#{node_name}[@name=\"#{name_local}\"]", { 'xs' => XML_SCHEMA }).first
|
120
|
+
return s.node_to_object(node) if node
|
121
|
+
end
|
119
122
|
|
120
|
-
|
123
|
+
nil
|
121
124
|
end
|
122
125
|
|
123
126
|
# Get reader object for node
|
@@ -169,9 +172,9 @@ module XSD
|
|
169
172
|
|
170
173
|
# Get namespace prefix from node name
|
171
174
|
# @param [String, nil] name Name to strip from
|
172
|
-
# @return String
|
175
|
+
# @return String, nil
|
173
176
|
def get_prefix(name)
|
174
|
-
name&.include?(':') ? name.split(':').first :
|
177
|
+
name&.include?(':') ? name.split(':').first : nil
|
175
178
|
end
|
176
179
|
|
177
180
|
# Return element documentation
|
@@ -8,7 +8,26 @@ module XSD
|
|
8
8
|
TYPE_PROPERTY = nil
|
9
9
|
|
10
10
|
include Based
|
11
|
-
include SimpleTyped
|
12
11
|
include AttributeContainer
|
12
|
+
|
13
|
+
# Nested group
|
14
|
+
# @!attribute group
|
15
|
+
# @return Group
|
16
|
+
child :group, :group
|
17
|
+
|
18
|
+
# Nested all
|
19
|
+
# @!attribute all
|
20
|
+
# @return All
|
21
|
+
child :all, :all
|
22
|
+
|
23
|
+
# Nested choice
|
24
|
+
# @!attribute choice
|
25
|
+
# @return Choice
|
26
|
+
child :choice, :choice
|
27
|
+
|
28
|
+
# Nested sequence
|
29
|
+
# @!attribute sequence
|
30
|
+
# @return Sequence
|
31
|
+
child :sequence, :sequence
|
13
32
|
end
|
14
33
|
end
|
data/lib/xsd/objects/import.rb
CHANGED
@@ -16,23 +16,23 @@ module XSD
|
|
16
16
|
property :schemaLocation, :string
|
17
17
|
|
18
18
|
# Get imported schema
|
19
|
-
# @return
|
19
|
+
# @return Schema
|
20
20
|
def imported_schema
|
21
|
-
|
22
|
-
return
|
21
|
+
known_schemas = reader.schemas_for_namespace(namespace)
|
22
|
+
return known_schemas.first if known_schemas.any?
|
23
23
|
|
24
24
|
unless schema_location
|
25
25
|
raise ImportError, "Schema location not provided for namespace '#{namespace}', use add_schema_xml()/add_schema_node()"
|
26
26
|
end
|
27
27
|
|
28
28
|
xml = reader.resource_resolver.call(schema_location, namespace)
|
29
|
-
|
29
|
+
new_schema = reader.add_schema_xml(xml)
|
30
30
|
|
31
|
-
unless namespace ==
|
32
|
-
raise ImportError, 'Import
|
31
|
+
unless namespace == new_schema.target_namespace
|
32
|
+
raise ImportError, 'Import namespace does not match imported schema targetNamespace'
|
33
33
|
end
|
34
34
|
|
35
|
-
|
35
|
+
new_schema
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module XSD
|
4
|
+
# The include element is used to add multiple schemas with the same target namespace to a document.
|
5
|
+
# Parent elements: schema
|
6
|
+
# https://www.w3schools.com/xml/el_include.asp
|
7
|
+
class Include < BaseObject
|
8
|
+
# Required. Specifies the URI to the schema to include in the target namespace of the containing schema
|
9
|
+
# @!attribute schema_location
|
10
|
+
# @return String
|
11
|
+
property :schemaLocation, :string
|
12
|
+
|
13
|
+
# Get imported schema
|
14
|
+
# @return Schema
|
15
|
+
def imported_schema
|
16
|
+
# cache included schema locally as it has no unique namespace to check in global registry
|
17
|
+
return @imported_schema if @imported_schema
|
18
|
+
|
19
|
+
xml = reader.resource_resolver.call(schema_location)
|
20
|
+
new_schema = reader.add_schema_xml(xml)
|
21
|
+
|
22
|
+
unless schema.target_namespace == new_schema.target_namespace
|
23
|
+
raise ImportError, 'Schema targetNamespace does not match included schema targetNamespace'
|
24
|
+
end
|
25
|
+
|
26
|
+
@imported_schema = new_schema
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -16,6 +16,26 @@ module XSD
|
|
16
16
|
fractionDigits length minLength maxLength enumeration whiteSpace pattern
|
17
17
|
].freeze
|
18
18
|
|
19
|
+
# Nested group
|
20
|
+
# @!attribute group
|
21
|
+
# @return Group
|
22
|
+
child :group, :group
|
23
|
+
|
24
|
+
# Nested all
|
25
|
+
# @!attribute all
|
26
|
+
# @return All
|
27
|
+
child :all, :all
|
28
|
+
|
29
|
+
# Nested choice
|
30
|
+
# @!attribute choice
|
31
|
+
# @return Choice
|
32
|
+
child :choice, :choice
|
33
|
+
|
34
|
+
# Nested sequence
|
35
|
+
# @!attribute sequence
|
36
|
+
# @return Sequence
|
37
|
+
child :sequence, :sequence
|
38
|
+
|
19
39
|
# Get restriction facets
|
20
40
|
# @return Hash
|
21
41
|
def facets
|
data/lib/xsd/objects/schema.rb
CHANGED
@@ -85,6 +85,11 @@ module XSD
|
|
85
85
|
# @return Array<Import>
|
86
86
|
child :imports, [:import]
|
87
87
|
|
88
|
+
# Schema includes
|
89
|
+
# @!attribute includes
|
90
|
+
# @return Array<Include>
|
91
|
+
child :includes, [:include]
|
92
|
+
|
88
93
|
# Get current schema object
|
89
94
|
# @return Schema
|
90
95
|
def schema
|
@@ -116,30 +121,31 @@ module XSD
|
|
116
121
|
end
|
117
122
|
|
118
123
|
# Check if namespace is a target namespace
|
119
|
-
# @param [String] namespace
|
124
|
+
# @param [String, nil] namespace
|
120
125
|
# @return Boolean
|
121
126
|
def targets_namespace?(namespace)
|
122
127
|
namespace == target_namespace || namespaces[namespace.empty? ? 'xmlns' : "xmlns:#{namespace}"] == target_namespace
|
123
128
|
end
|
124
129
|
|
125
|
-
# Override map_children on schema to get objects from all
|
130
|
+
# Override map_children on schema to get objects from all loaded schemas
|
126
131
|
# @param [Symbol] name
|
127
132
|
# @return Array<BaseObject>
|
128
133
|
def map_children(name, cache = {})
|
129
134
|
super(name) + import_map_children(name, cache)
|
130
135
|
end
|
131
136
|
|
132
|
-
# Get children from all
|
137
|
+
# Get children from all loaded schemas
|
133
138
|
# @param [Symbol] name
|
134
139
|
# @return Array<BaseObject>
|
135
140
|
def import_map_children(name, cache)
|
136
|
-
return [] if name.to_sym
|
141
|
+
return [] if %i[import include].include?(name.to_sym)
|
137
142
|
|
138
|
-
imports.map do |import|
|
139
|
-
|
143
|
+
(includes + imports).map do |import|
|
144
|
+
key = import.respond_to?(:namespace) && import.namespace ? import.namespace : import.schema_location
|
145
|
+
if cache.key?(key)
|
140
146
|
nil
|
141
147
|
else
|
142
|
-
cache[
|
148
|
+
cache[key] = true
|
143
149
|
import.imported_schema.map_children(name, cache)
|
144
150
|
end
|
145
151
|
end.compact.flatten
|
data/lib/xsd/version.rb
CHANGED
data/lib/xsd/xml.rb
CHANGED
@@ -31,6 +31,7 @@ module XSD
|
|
31
31
|
'complexContent' => ComplexContent,
|
32
32
|
'extension' => Extension,
|
33
33
|
'import' => Import,
|
34
|
+
'include' => Include,
|
34
35
|
'simpleType' => SimpleType,
|
35
36
|
'all' => All,
|
36
37
|
'restriction' => Restriction,
|
@@ -63,6 +64,10 @@ module XSD
|
|
63
64
|
'pattern' => Facet
|
64
65
|
}.freeze
|
65
66
|
|
67
|
+
# Create reader from a file path
|
68
|
+
# @param [String] path
|
69
|
+
# @param [Hash] options
|
70
|
+
# @return XML
|
66
71
|
def self.open(path, **options)
|
67
72
|
reader = new(**options)
|
68
73
|
reader.add_schema_xml(File.read(path))
|
@@ -92,8 +97,8 @@ module XSD
|
|
92
97
|
Nokogiri::XML(xml)
|
93
98
|
end
|
94
99
|
|
95
|
-
#
|
96
|
-
# @return
|
100
|
+
# Add schema xml to reader instance
|
101
|
+
# @return Schema
|
97
102
|
def add_schema_xml(xml)
|
98
103
|
doc = read_document(xml)
|
99
104
|
raise Error, 'Schema node not found, xml does not seem to be a valid XSD' unless doc.root&.name == 'schema'
|
@@ -101,15 +106,14 @@ module XSD
|
|
101
106
|
add_schema_node(doc.root)
|
102
107
|
end
|
103
108
|
|
104
|
-
#
|
109
|
+
# Add schema node to reader instance
|
105
110
|
# @return Schema
|
106
111
|
def add_schema_node(node)
|
107
112
|
raise Error, 'Added schema must be of type Nokogiri::XML::Node' unless node.is_a?(Nokogiri::XML::Node)
|
108
113
|
|
109
|
-
|
110
|
-
schemas.push(
|
111
|
-
|
112
|
-
schema
|
114
|
+
new_schema = Schema.new(options.merge(node: node, reader: self))
|
115
|
+
schemas.push(new_schema)
|
116
|
+
new_schema
|
113
117
|
end
|
114
118
|
|
115
119
|
# Add prefixes defined outside of processed schemas, for example in WSDL document
|
@@ -126,10 +130,11 @@ module XSD
|
|
126
130
|
end
|
127
131
|
|
128
132
|
# Get schema by namespace or namespace prefix
|
129
|
-
# @
|
130
|
-
|
133
|
+
# @param [String, nil] namespace
|
134
|
+
# @return Array<Schema>
|
135
|
+
def schemas_for_namespace(namespace)
|
131
136
|
namespace = namespace_prefixes[namespace] if namespace_prefixes.key?(namespace)
|
132
|
-
schemas.
|
137
|
+
schemas.select { |schema| schema.target_namespace == namespace }
|
133
138
|
end
|
134
139
|
|
135
140
|
def [](*args)
|
data/lib/xsd.rb
CHANGED
@@ -18,6 +18,7 @@ require 'xsd/objects/simple_content'
|
|
18
18
|
require 'xsd/objects/complex_content'
|
19
19
|
require 'xsd/objects/extension'
|
20
20
|
require 'xsd/objects/import'
|
21
|
+
require 'xsd/objects/include'
|
21
22
|
require 'xsd/objects/restriction'
|
22
23
|
require 'xsd/objects/group'
|
23
24
|
require 'xsd/objects/all'
|
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: 2.
|
4
|
+
version: 2.1.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-07-
|
11
|
+
date: 2023-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: builder
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- lib/xsd/objects/field.rb
|
91
91
|
- lib/xsd/objects/group.rb
|
92
92
|
- lib/xsd/objects/import.rb
|
93
|
+
- lib/xsd/objects/include.rb
|
93
94
|
- lib/xsd/objects/key.rb
|
94
95
|
- lib/xsd/objects/keyref.rb
|
95
96
|
- lib/xsd/objects/list.rb
|