rxsd 0.2
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.
- data/COPYING +8 -0
- data/LICENSE +165 -0
- data/README +19 -0
- data/bin/rxsd-test.rb +41 -0
- data/lib/rxsd.rb +22 -0
- data/lib/rxsd/builder.rb +159 -0
- data/lib/rxsd/builders/ruby_class.rb +79 -0
- data/lib/rxsd/builders/ruby_definition.rb +54 -0
- data/lib/rxsd/builders/ruby_object.rb +59 -0
- data/lib/rxsd/builtin_types.rb +82 -0
- data/lib/rxsd/common.rb +69 -0
- data/lib/rxsd/exceptions.rb +25 -0
- data/lib/rxsd/libxml_adapter.rb +77 -0
- data/lib/rxsd/loader.rb +33 -0
- data/lib/rxsd/parser.rb +135 -0
- data/lib/rxsd/resolver.rb +52 -0
- data/lib/rxsd/translator.rb +127 -0
- data/lib/rxsd/xml.rb +92 -0
- data/lib/rxsd/xsd/attribute.rb +119 -0
- data/lib/rxsd/xsd/attribute_group.rb +90 -0
- data/lib/rxsd/xsd/choice.rb +109 -0
- data/lib/rxsd/xsd/complex_content.rb +87 -0
- data/lib/rxsd/xsd/complex_type.rb +136 -0
- data/lib/rxsd/xsd/element.rb +162 -0
- data/lib/rxsd/xsd/extension.rb +138 -0
- data/lib/rxsd/xsd/group.rb +100 -0
- data/lib/rxsd/xsd/list.rb +101 -0
- data/lib/rxsd/xsd/restriction.rb +186 -0
- data/lib/rxsd/xsd/schema.rb +114 -0
- data/lib/rxsd/xsd/sequence.rb +108 -0
- data/lib/rxsd/xsd/simple_content.rb +86 -0
- data/lib/rxsd/xsd/simple_type.rb +101 -0
- metadata +106 -0
@@ -0,0 +1,109 @@
|
|
1
|
+
# The XSD Choice definition
|
2
|
+
#
|
3
|
+
# Copyright (C) 2009 Mohammed Morsi <movitto@yahoo.com>
|
4
|
+
# See COPYING for the License of this software
|
5
|
+
|
6
|
+
module RXSD
|
7
|
+
module XSD
|
8
|
+
|
9
|
+
# XSD Choice defintion
|
10
|
+
# http://www.w3schools.com/Schema/el_choice.asp
|
11
|
+
class Choice
|
12
|
+
|
13
|
+
# choice attributes
|
14
|
+
attr_accessor :id, :maxOccurs, :minOccurs
|
15
|
+
|
16
|
+
# choice children
|
17
|
+
attr_accessor :elements, :groups, :choices, :sequences
|
18
|
+
|
19
|
+
# choice parent
|
20
|
+
attr_accessor :parent
|
21
|
+
|
22
|
+
# xml tag name
|
23
|
+
def self.tag_name
|
24
|
+
"choice"
|
25
|
+
end
|
26
|
+
|
27
|
+
# return xsd node info
|
28
|
+
def info
|
29
|
+
"choice id: #{@id}"
|
30
|
+
end
|
31
|
+
|
32
|
+
# returns array of all children
|
33
|
+
def children
|
34
|
+
@elements + @groups + @choices + @sequences
|
35
|
+
end
|
36
|
+
|
37
|
+
# node passed in should be a xml node representing the group
|
38
|
+
def self.from_xml(node)
|
39
|
+
choice = Choice.new
|
40
|
+
choice.parent = node.parent.related
|
41
|
+
node.related = choice
|
42
|
+
|
43
|
+
# TODO choice attributes: | anyAttributes
|
44
|
+
choice.id = node.attrs["id"]
|
45
|
+
|
46
|
+
choice.maxOccurs = node.attrs.has_key?("maxOccurs") ?
|
47
|
+
(node.attrs["maxOccurs"] == "unbounded" ? "unbounded" : node.attrs["maxOccurs"].to_i) : 1
|
48
|
+
choice.minOccurs = node.attrs.has_key?("minOccurs") ?
|
49
|
+
(node.attrs["minOccurs"] == "unbounded" ? "unbounded" : node.attrs["minOccurs"].to_i) : 1
|
50
|
+
|
51
|
+
# TODO choice children: | any
|
52
|
+
choice.elements = node.children_objs Element
|
53
|
+
choice.groups = node.children_objs Group
|
54
|
+
choice.choices = node.children_objs Choice
|
55
|
+
choice.sequences = node.children_objs Sequence
|
56
|
+
|
57
|
+
return choice
|
58
|
+
end
|
59
|
+
|
60
|
+
# resolve hanging references given complete xsd node object array
|
61
|
+
def resolve(node_objs)
|
62
|
+
end
|
63
|
+
|
64
|
+
# convert choice to array of class builders
|
65
|
+
def to_class_builders
|
66
|
+
# FIXME enforce "only one attribute must be set"
|
67
|
+
|
68
|
+
unless defined? @class_builders
|
69
|
+
@class_builders = []
|
70
|
+
@elements.each { |e|
|
71
|
+
@class_builders.push e.to_class_builder
|
72
|
+
}
|
73
|
+
@groups.each { |g|
|
74
|
+
g.to_class_builders.each { |gcb|
|
75
|
+
@class_builders.push gcb
|
76
|
+
}
|
77
|
+
}
|
78
|
+
@choices.each { |c|
|
79
|
+
c.to_class_builders.each { |ccb|
|
80
|
+
@class_builders.push ccb
|
81
|
+
}
|
82
|
+
}
|
83
|
+
@sequences.each { |s|
|
84
|
+
s.to_class_builders.each { |scb|
|
85
|
+
@class_builders.push scb
|
86
|
+
}
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
return @class_builders
|
91
|
+
end
|
92
|
+
|
93
|
+
# return all child attributes assocaited w/ choice
|
94
|
+
def child_attributes
|
95
|
+
atts = []
|
96
|
+
@elements.each { |elem|
|
97
|
+
eca = elem.child_attributes
|
98
|
+
atts += eca unless eca.nil?
|
99
|
+
} unless @elements.nil?
|
100
|
+
@sequences.each { |seq| atts += seq.child_attributes } unless @sequences.nil?
|
101
|
+
@choices.each { |ch| atts += ch.child_attributes } unless @choices.nil?
|
102
|
+
@groups.each { |gr| atts += gr.child_attributes } unless @groups.nil?
|
103
|
+
return atts
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end # module XSD
|
109
|
+
end # module RXSD
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# The XSD ComplexContent definition
|
2
|
+
#
|
3
|
+
# Copyright (C) 2009 Mohammed Morsi <movitto@yahoo.com>
|
4
|
+
# See COPYING for the License of this software
|
5
|
+
|
6
|
+
module RXSD
|
7
|
+
module XSD
|
8
|
+
|
9
|
+
# XSD ComplexContent defintion
|
10
|
+
# http://www.w3schools.com/Schema/el_complexcontent.asp
|
11
|
+
class ComplexContent
|
12
|
+
|
13
|
+
# complex content attributes
|
14
|
+
attr_accessor :id, :mixed
|
15
|
+
|
16
|
+
# complex content children
|
17
|
+
attr_accessor :restriction, :extension
|
18
|
+
|
19
|
+
# complex content parent
|
20
|
+
attr_accessor :parent
|
21
|
+
|
22
|
+
# xml tag name
|
23
|
+
def self.tag_name
|
24
|
+
"complexContent"
|
25
|
+
end
|
26
|
+
|
27
|
+
# return xsd node info
|
28
|
+
def info
|
29
|
+
"complexContent id: #{@id}"
|
30
|
+
end
|
31
|
+
|
32
|
+
# returns array of all children
|
33
|
+
def children
|
34
|
+
c = []
|
35
|
+
c.push @restriction unless @restriction.nil?
|
36
|
+
c.push @extension unless @extension.nil?
|
37
|
+
return c
|
38
|
+
end
|
39
|
+
|
40
|
+
# node passed in should be a xml node representing the group
|
41
|
+
def self.from_xml(node)
|
42
|
+
complex_content = ComplexContent.new
|
43
|
+
complex_content.parent = node.parent.related
|
44
|
+
node.related = complex_content
|
45
|
+
|
46
|
+
# TODO group attributes: | anyAttributes
|
47
|
+
complex_content.id = node.attrs["id"]
|
48
|
+
complex_content.mixed = node.attrs.has_key?("mixed") ? node.attrs["mixed"].to_b : false
|
49
|
+
|
50
|
+
complex_content.restriction = node.child_obj Restriction
|
51
|
+
complex_content.extension = node.child_obj Extension
|
52
|
+
|
53
|
+
return complex_content
|
54
|
+
end
|
55
|
+
|
56
|
+
# resolve hanging references given complete xsd node object array
|
57
|
+
def resolve(node_objs)
|
58
|
+
end
|
59
|
+
|
60
|
+
# convert complex content to class builder
|
61
|
+
def to_class_builder(cb = nil)
|
62
|
+
unless defined? @class_builder
|
63
|
+
# dispatch to child restriction/extension
|
64
|
+
@class_builder = cb
|
65
|
+
|
66
|
+
if !@restriction.nil?
|
67
|
+
@class_builder = @restriction.to_class_builder(@class_builder)
|
68
|
+
elsif !@extension.nil?
|
69
|
+
@class_builder = @extension.to_class_builder(@class_builder)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
return @class_builder
|
74
|
+
end
|
75
|
+
|
76
|
+
# return all child attributes associated w/ complex content
|
77
|
+
def child_attributes
|
78
|
+
atts = []
|
79
|
+
atts += @restriction.child_attributes unless @restriction.nil?
|
80
|
+
atts += @extension.child_attributes unless @extension.nil?
|
81
|
+
return atts
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end # module XSD
|
87
|
+
end # module RXSD
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# The XSD ComplexType definition
|
2
|
+
#
|
3
|
+
# Copyright (C) 2009 Mohammed Morsi <movitto@yahoo.com>
|
4
|
+
# See COPYING for the License of this software
|
5
|
+
|
6
|
+
module RXSD
|
7
|
+
module XSD
|
8
|
+
|
9
|
+
# XSD ComplexType defintion
|
10
|
+
# http://www.w3schools.com/Schema/el_simpletype.asp
|
11
|
+
class ComplexType
|
12
|
+
|
13
|
+
# complex type attribute values
|
14
|
+
attr_accessor :id, :name, :abstract, :mixed
|
15
|
+
|
16
|
+
# complex type children
|
17
|
+
attr_accessor :attributes, :attribute_groups,
|
18
|
+
:simple_content, :complex_content,
|
19
|
+
:choice, :group, :sequence
|
20
|
+
|
21
|
+
# complexType parent
|
22
|
+
attr_accessor :parent
|
23
|
+
|
24
|
+
# xml tag name
|
25
|
+
def self.tag_name
|
26
|
+
"complexType"
|
27
|
+
end
|
28
|
+
|
29
|
+
# return xsd node info
|
30
|
+
def info
|
31
|
+
"complexType id: #{@id} name: #{@name}"
|
32
|
+
end
|
33
|
+
|
34
|
+
# returns array of all children
|
35
|
+
def children
|
36
|
+
(@attributes + @attribute_groups).push(@simple_content).push(@complex_content).push(@choice).push(@group).push(@sequence)
|
37
|
+
end
|
38
|
+
|
39
|
+
# node passed in should be a xml node representing the complex type
|
40
|
+
def self.from_xml(node)
|
41
|
+
complexType = ComplexType.new
|
42
|
+
complexType.parent = node.parent.related
|
43
|
+
node.related = complexType
|
44
|
+
|
45
|
+
# TODO complexType attributes: | block, final, anyAttributes
|
46
|
+
|
47
|
+
complexType.id = node.attrs['id']
|
48
|
+
complexType.name = node.attrs['name']
|
49
|
+
complexType.abstract = node.attrs.has_key?('abstract') ? node.attrs['abstract'].to_b : false
|
50
|
+
|
51
|
+
if node.children.find { |c| c.name == SimpleContent.tag_name }.nil?
|
52
|
+
complexType.mixed = node.attrs.has_key?('mixed') ? node.attrs['mixed'].to_b : false
|
53
|
+
else
|
54
|
+
complexType.mixed = false
|
55
|
+
end
|
56
|
+
|
57
|
+
# TODO complexType children: | all, anyAttribute,
|
58
|
+
complexType.attributes = node.children_objs Attribute
|
59
|
+
complexType.attribute_groups = node.children_objs AttributeGroup
|
60
|
+
complexType.simple_content = node.child_obj SimpleContent
|
61
|
+
complexType.complex_content = node.child_obj ComplexContent
|
62
|
+
complexType.group = node.child_obj Group
|
63
|
+
complexType.choice = node.child_obj Choice
|
64
|
+
complexType.sequence = node.child_obj Sequence
|
65
|
+
|
66
|
+
return complexType
|
67
|
+
end
|
68
|
+
|
69
|
+
# resolve hanging references given complete xsd node object array
|
70
|
+
def resolve(node_objs)
|
71
|
+
end
|
72
|
+
|
73
|
+
# convert complex type to class builder
|
74
|
+
def to_class_builder
|
75
|
+
unless defined? @class_builder
|
76
|
+
# dispatch to simple / complex content to get class builder
|
77
|
+
@class_builder = ClassBuilder.new
|
78
|
+
|
79
|
+
if !@simple_content.nil?
|
80
|
+
@simple_content.to_class_builder(@class_builder)
|
81
|
+
elsif !@complex_content.nil?
|
82
|
+
@complex_content.to_class_builder(@class_builder)
|
83
|
+
#else
|
84
|
+
#@class_builder = ClassBuilder.new
|
85
|
+
end
|
86
|
+
|
87
|
+
@class_builder.klass_name = @name.camelize unless @name.nil?
|
88
|
+
|
89
|
+
@attributes.each { |att|
|
90
|
+
@class_builder.attribute_builders.push att.to_class_builder
|
91
|
+
}
|
92
|
+
@attribute_groups.each { |atg|
|
93
|
+
atg.to_class_builders.each { |atcb|
|
94
|
+
@class_builder.attribute_builders.push atcb
|
95
|
+
}
|
96
|
+
}
|
97
|
+
|
98
|
+
if !@group.nil?
|
99
|
+
@group.to_class_builders.each { |gcb|
|
100
|
+
@class_builder.attribute_builders.push gcb
|
101
|
+
}
|
102
|
+
end
|
103
|
+
|
104
|
+
if !@choice.nil?
|
105
|
+
@choice.to_class_builders.each { |ccb|
|
106
|
+
@class_builder.attribute_builders.push ccb
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
if !@sequence.nil?
|
111
|
+
@sequence.to_class_builders.each { |scb|
|
112
|
+
@class_builder.attribute_builders.push scb
|
113
|
+
}
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
return @class_builder
|
118
|
+
end
|
119
|
+
|
120
|
+
# return all child attributes assocaited w/ complex type
|
121
|
+
def child_attributes
|
122
|
+
atts = []
|
123
|
+
atts += @choice.child_attributes unless @choice.nil?
|
124
|
+
atts += @sequence.child_attributes unless @sequence.nil?
|
125
|
+
atts += @group.child_attributes unless @group.nil?
|
126
|
+
atts += @simple_content.child_attributes unless @simple_content.nil?
|
127
|
+
atts += @complex_content.child_attributes unless @complex_content.nil?
|
128
|
+
@attribute_groups.each { |atg| atts += atg.child_attributes } unless @attribute_groups.nil?
|
129
|
+
@attributes.each { |att| atts += att.child_attributes } unless @attributes.nil?
|
130
|
+
return atts
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
end # module XSD
|
136
|
+
end # module RXSD
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# The XSD Element definition
|
2
|
+
#
|
3
|
+
# Copyright (C) 2009 Mohammed Morsi <movitto@yahoo.com>
|
4
|
+
# See COPYING for the License of this software
|
5
|
+
|
6
|
+
module RXSD
|
7
|
+
module XSD
|
8
|
+
|
9
|
+
# XSD Element defintion
|
10
|
+
# http://www.w3schools.com/Schema/el_element.asp
|
11
|
+
class Element
|
12
|
+
|
13
|
+
# element attribute values
|
14
|
+
attr_accessor :id, :name, :type,
|
15
|
+
:nillable, :abstract, :ref,
|
16
|
+
:substitionGroup, :form, :maxOccurs,
|
17
|
+
:minOccurs, :default, :fixed
|
18
|
+
|
19
|
+
# simple type in element
|
20
|
+
attr_accessor :simple_type
|
21
|
+
|
22
|
+
# complex type in element
|
23
|
+
attr_accessor :complex_type
|
24
|
+
|
25
|
+
# element parent
|
26
|
+
attr_accessor :parent
|
27
|
+
|
28
|
+
# xml tag name
|
29
|
+
def self.tag_name
|
30
|
+
"element"
|
31
|
+
end
|
32
|
+
|
33
|
+
# return xsd node info
|
34
|
+
def info
|
35
|
+
"element id: #{@id} name: #{@name} type: #{@type.class} ref: #{ref.nil? ? "" : ref.class == String ? ref : ref.name} "
|
36
|
+
end
|
37
|
+
|
38
|
+
# returns array of all children
|
39
|
+
def children
|
40
|
+
c = []
|
41
|
+
c.push @simple_type unless @simple_type.nil?
|
42
|
+
c.push @complex_type unless @complex_type.nil?
|
43
|
+
return c
|
44
|
+
end
|
45
|
+
|
46
|
+
# node passed in should be a xml node representing the element
|
47
|
+
def self.from_xml(node)
|
48
|
+
element = Element.new
|
49
|
+
element.parent = node.parent.related
|
50
|
+
node.related = element
|
51
|
+
|
52
|
+
# TODO element attrs: | block / final
|
53
|
+
# TODO element children: | key, keyref, unique
|
54
|
+
|
55
|
+
element.id = node.attrs["id"]
|
56
|
+
element.name = node.attrs["name"]
|
57
|
+
element.type = node.attrs["type"]
|
58
|
+
element.nillable = node.attrs.has_key?("nillable") ? node.attrs["nillable"].to_b : false
|
59
|
+
element.abstract = node.attrs.has_key?("abstract") ? node.attrs["abstract"].to_b : false
|
60
|
+
|
61
|
+
unless node.parent.name == Schema.tag_name
|
62
|
+
# FIXME ignoring reference namepsace prefix (if any) for now
|
63
|
+
ref = node.attrs["ref"]
|
64
|
+
ref = ref.split(':')[1] if !(ref.nil? || ref.index(":").nil?)
|
65
|
+
element.ref = ref
|
66
|
+
|
67
|
+
element.substitionGroup = node.attrs["substitionGroup"]
|
68
|
+
element.form = node.attrs.has_key?("form") ?
|
69
|
+
node.attrs["form"] :
|
70
|
+
node.root.attrs["elementFormDefault"]
|
71
|
+
|
72
|
+
element.maxOccurs = node.attrs.has_key?("maxOccurs") ?
|
73
|
+
(node.attrs["maxOccurs"] == "unbounded" ? "unbounded" : node.attrs["maxOccurs"].to_i) : 1
|
74
|
+
element.minOccurs = node.attrs.has_key?("minOccurs") ?
|
75
|
+
(node.attrs["minOccurs"] == "unbounded" ? "unbounded" : node.attrs["minOccurs"].to_i) : 1
|
76
|
+
|
77
|
+
else
|
78
|
+
element.form = node.parent.attrs["elementFormDefault"]
|
79
|
+
end
|
80
|
+
|
81
|
+
if node.text? || !node.children.find { |c| c.name == SimpleType.tag_name }.nil?
|
82
|
+
element.default = node.attrs["default"]
|
83
|
+
element.fixed = node.attrs["fixed"]
|
84
|
+
end
|
85
|
+
|
86
|
+
element.simple_type = node.child_obj SimpleType
|
87
|
+
element.complex_type = node.child_obj ComplexType
|
88
|
+
|
89
|
+
return element
|
90
|
+
end
|
91
|
+
|
92
|
+
# resolve hanging references given complete xsd node object array
|
93
|
+
def resolve(node_objs)
|
94
|
+
unless @type.nil?
|
95
|
+
builtin = Parser.parse_builtin_type @type
|
96
|
+
simple = node_objs[SimpleType].find { |no| no.name == @type }
|
97
|
+
complex = node_objs[ComplexType].find { |no| no.name == @type }
|
98
|
+
if !builtin.nil?
|
99
|
+
@type = builtin
|
100
|
+
elsif !simple.nil?
|
101
|
+
@type = simple
|
102
|
+
elsif !complex.nil?
|
103
|
+
@type = complex
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
unless @ref.nil?
|
108
|
+
@ref = node_objs[Element].find { |no| no.name == @ref }
|
109
|
+
end
|
110
|
+
|
111
|
+
unless @substitionGroup.nil?
|
112
|
+
@substitutionGroup = node_objs[Element].find { |no| no.name == @substitionGroup }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# convert element to class builder
|
117
|
+
def to_class_builder
|
118
|
+
unless defined? @class_builder
|
119
|
+
@class_builder = nil
|
120
|
+
|
121
|
+
if !@ref.nil?
|
122
|
+
@class_builder = @ref.to_class_builder
|
123
|
+
|
124
|
+
elsif !@type.nil?
|
125
|
+
if @type.class == SimpleType || @type.class == ComplexType
|
126
|
+
@class_builder = @type.to_class_builder.clone # need to clone here as we're refering to a type that may be used elsewhere
|
127
|
+
else
|
128
|
+
@class_builder = ClassBuilder.new :klass => @type
|
129
|
+
end
|
130
|
+
|
131
|
+
elsif !@simple_type.nil?
|
132
|
+
@class_builder = @simple_type.to_class_builder
|
133
|
+
|
134
|
+
elsif !@complex_type.nil?
|
135
|
+
@class_builder = @complex_type.to_class_builder
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
@class_builder.klass_name = @name.camelize unless @class_builder.nil? || @name == "" || @name.nil?
|
140
|
+
end
|
141
|
+
|
142
|
+
return @class_builder
|
143
|
+
end
|
144
|
+
|
145
|
+
# return all child attributes associated w/ element
|
146
|
+
def child_attributes
|
147
|
+
if !@ref.nil?
|
148
|
+
return @ref.child_attributes
|
149
|
+
elsif[SimpleType, ComplexType].include? @type.class
|
150
|
+
return @type.child_attributes
|
151
|
+
elsif !@simple_type.nil?
|
152
|
+
return @simple_type.child_attributes
|
153
|
+
elsif !@complex_type.nil?
|
154
|
+
return @complex_type.child_attributes
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
end # module XSD
|
162
|
+
end # module RXSD
|