rxsd 0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|