rgen-xsd 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +4 -0
- data/MIT-LICENSE +21 -0
- data/README +16 -0
- data/Rakefile +45 -0
- data/lib/rgen/xsd/1.0/datatypes.xml +1117 -0
- data/lib/rgen/xsd/1.0/metamodel.rb +413 -0
- data/lib/rgen/xsd/1.0/rakefile +3 -0
- data/lib/rgen/xsd/1.0/readme.txt +6 -0
- data/lib/rgen/xsd/1.0/structures.xml +1235 -0
- data/lib/rgen/xsd/1.1/datatypes.xml +491 -0
- data/lib/rgen/xsd/1.1/metamodel.rb +488 -0
- data/lib/rgen/xsd/1.1/rakefile +3 -0
- data/lib/rgen/xsd/1.1/readme.txt +6 -0
- data/lib/rgen/xsd/1.1/structures.xml +1479 -0
- data/lib/rgen/xsd/metamodel_generator.rb +110 -0
- data/lib/rgen/xsd/metamodel_modification_helper.rb +41 -0
- data/lib/rgen/xsd/particle.rb +169 -0
- data/lib/rgen/xsd/simple_type.rb +87 -0
- data/lib/rgen/xsd/xml/readme.txt +6 -0
- data/lib/rgen/xsd/xml/xml.xsd +145 -0
- data/lib/rgen/xsd/xml_schema_metamodel_ext.rb +54 -0
- data/lib/rgen/xsd/xsd_instantiator.rb +83 -0
- data/lib/rgen/xsd/xsd_to_ecore.rb +325 -0
- data/lib/rgen/xsd/xsi_instantiator.rb +230 -0
- metadata +87 -0
@@ -0,0 +1,110 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)+"/../../")
|
2
|
+
|
3
|
+
require "rgen/environment"
|
4
|
+
require "rgen/util/name_helper"
|
5
|
+
require 'mmgen/metamodel_generator'
|
6
|
+
|
7
|
+
require "rgen/xsd/xsd_instantiator"
|
8
|
+
require "rgen/xsd/metamodel_modification_helper"
|
9
|
+
require 'optparse'
|
10
|
+
|
11
|
+
include RGen::Util::NameHelper
|
12
|
+
include RGen::XSD::MetamodelModificationHelper
|
13
|
+
|
14
|
+
options = {}
|
15
|
+
optparse = OptionParser.new do|opts|
|
16
|
+
opts.banner = "Usage: metamodel_generator.rb [options] <schema file>+"
|
17
|
+
|
18
|
+
opts.on( '--mm VERSION', 'XML schema version: 1.0 or 1.1' ) do |v|
|
19
|
+
options[:mm] = v
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on('-o FILE', "Output metamodel file") do |f|
|
23
|
+
options[:outfile] = f
|
24
|
+
end
|
25
|
+
end
|
26
|
+
optparse.parse!
|
27
|
+
if !options[:mm]
|
28
|
+
puts "Schema version not specified"
|
29
|
+
exit
|
30
|
+
end
|
31
|
+
if !options[:outfile]
|
32
|
+
puts "Output file not specified"
|
33
|
+
exit
|
34
|
+
end
|
35
|
+
|
36
|
+
case options[:mm]
|
37
|
+
when "1.0"
|
38
|
+
require "rgen/xsd/1.0/metamodel"
|
39
|
+
when "1.1"
|
40
|
+
require "rgen/xsd/1.1/metamodel"
|
41
|
+
else
|
42
|
+
puts "Unknown schema version: #{options[:mm]}"
|
43
|
+
exit
|
44
|
+
end
|
45
|
+
XMLSchemaMetamodel = MM::W3Org2001XMLSchema
|
46
|
+
|
47
|
+
env = RGen::Environment.new
|
48
|
+
mm = XMLSchemaMetamodel
|
49
|
+
inst = RGen::XSD::XSDInstantiator.new(env, mm)
|
50
|
+
|
51
|
+
ARGV.each do |fn|
|
52
|
+
inst.instantiate(fn)
|
53
|
+
end
|
54
|
+
|
55
|
+
problems = []
|
56
|
+
inst.resolve(problems)
|
57
|
+
|
58
|
+
if problems.size > 0
|
59
|
+
problems.each do |p|
|
60
|
+
puts p
|
61
|
+
end
|
62
|
+
puts "#{problems.size} problems, stop."
|
63
|
+
exit
|
64
|
+
end
|
65
|
+
|
66
|
+
require "rgen/xsd/xml_schema_metamodel_ext"
|
67
|
+
require "rgen/xsd/xsd_to_ecore"
|
68
|
+
|
69
|
+
sch = env.find(:class => XMLSchemaMetamodel::Element, :name => "schema").first
|
70
|
+
|
71
|
+
env_ecore = RGen::Environment.new
|
72
|
+
trans = RGen::XSD::XSDToEcoreTransformer.new(env, env_ecore)
|
73
|
+
root = trans.transform
|
74
|
+
|
75
|
+
class_complexType = env_ecore.find(:class => RGen::ECore::EClass, :name => "ComplexType").first
|
76
|
+
class_simpleType = env_ecore.find(:class => RGen::ECore::EClass, :name => "SimpleType").first
|
77
|
+
class_element = env_ecore.find(:class => RGen::ECore::EClass, :name => "Element").first
|
78
|
+
class_group = env_ecore.find(:class => RGen::ECore::EClass, :name => "Group").first
|
79
|
+
class_attribute = env_ecore.find(:class => RGen::ECore::EClass, :name => "Attribute").first
|
80
|
+
class_attributeGroup = env_ecore.find(:class => RGen::ECore::EClass, :name => "AttributeGroup").first
|
81
|
+
|
82
|
+
# insert Type class as supertype of ComplexType and SimpleType
|
83
|
+
class_type = env_ecore.new(RGen::ECore::EClass, :name => "Type", :ePackage => class_complexType.ePackage,
|
84
|
+
:eSuperTypes => class_complexType.eSuperTypes)
|
85
|
+
class_complexType.eSuperTypes = [class_type]
|
86
|
+
class_simpleType.eSuperTypes = [class_type]
|
87
|
+
|
88
|
+
# explicit references
|
89
|
+
attribute_to_reference(env_ecore, "RestrictionType#base", class_type)
|
90
|
+
attribute_to_reference(env_ecore, "RestrictionTYPE#base", class_type)
|
91
|
+
attribute_to_reference(env_ecore, "ExtensionType#base", class_type)
|
92
|
+
attribute_to_reference(env_ecore, "Element#ref", class_element)
|
93
|
+
attribute_to_reference(env_ecore, "Element#type", class_type)
|
94
|
+
attribute_to_reference(env_ecore, "Group#ref", class_group)
|
95
|
+
attribute_to_reference(env_ecore, "AttributeGroup#ref", class_attributeGroup)
|
96
|
+
attribute_to_reference(env_ecore, "Attribute#ref", class_attribute)
|
97
|
+
attribute_to_reference(env_ecore, "Attribute#type", class_simpleType)
|
98
|
+
attribute_to_reference(env_ecore, "Element#substitutionGroup", class_element)
|
99
|
+
attribute_to_reference(env_ecore, "ListTYPE#itemType", class_simpleType)
|
100
|
+
attribute_to_reference(env_ecore, "UnionTYPE#memberTypes", class_simpleType)
|
101
|
+
|
102
|
+
# bidirectional references
|
103
|
+
create_opposite(env_ecore, "Element#substitutionGroup", "substitutes", -1)
|
104
|
+
create_opposite(env_ecore, "Element#complexType", "containingElement", 1)
|
105
|
+
create_opposite(env_ecore, "Element#simpleType", "containingElement", 1)
|
106
|
+
create_opposite(env_ecore, "Attribute#simpleType", "containingAttribute", 1)
|
107
|
+
|
108
|
+
include MMGen::MetamodelGenerator
|
109
|
+
generateMetamodel(root, options[:outfile])
|
110
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module RGen
|
2
|
+
|
3
|
+
module XSD
|
4
|
+
|
5
|
+
module MetamodelModificationHelper
|
6
|
+
|
7
|
+
def find_feature(env, desc)
|
8
|
+
env.find(:class => RGen::ECore::EStructuralFeature, :name => desc.split("#").last).
|
9
|
+
find{|f| f.eContainingClass.name == desc.split("#").first}
|
10
|
+
end
|
11
|
+
|
12
|
+
def attribute_to_reference(env, desc, target)
|
13
|
+
a = find_feature(env, desc)
|
14
|
+
r = env.new(RGen::ECore::EReference, Hash[
|
15
|
+
RGen::ECore::EStructuralFeature.ecore.eAllStructuralFeatures.collect do |f|
|
16
|
+
next if f.derived
|
17
|
+
p = [f.name, a.getGeneric(f.name)]
|
18
|
+
if f.many
|
19
|
+
a.setGeneric(f.name, [])
|
20
|
+
else
|
21
|
+
a.setGeneric(f.name, nil)
|
22
|
+
end
|
23
|
+
p
|
24
|
+
end])
|
25
|
+
r.eType = target
|
26
|
+
r
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_opposite(env, desc, name, upper_bound)
|
30
|
+
r = find_feature(env, desc)
|
31
|
+
r.eOpposite =
|
32
|
+
env.new(RGen::ECore::EReference, :name => name, :eType => r.eContainingClass,
|
33
|
+
:eContainingClass => r.eType, :upperBound => upper_bound, :eOpposite => r)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module RGen
|
2
|
+
module XSD
|
3
|
+
module Particle
|
4
|
+
|
5
|
+
# helper structure representing a particle or particle tree
|
6
|
+
# particles of kind :choice, :sequence or :all can have child particles
|
7
|
+
Particle = Struct.new(:kind, :children, :minOccurs, :maxOccurs, :node)
|
8
|
+
|
9
|
+
# builds a flat list of the element particles contained in +node+
|
10
|
+
# to be used for ComplexType and complex content extensions
|
11
|
+
def element_particles(node)
|
12
|
+
trees = build_particles_trees(node)
|
13
|
+
if trees.size == 1
|
14
|
+
flatten_particle_tree(trees.first)
|
15
|
+
elsif trees.size > 1
|
16
|
+
puts "WARN: only one particle expected as a content model"
|
17
|
+
[]
|
18
|
+
else
|
19
|
+
[]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_substitution_particles(particles)
|
24
|
+
result = []
|
25
|
+
particles.each do |p|
|
26
|
+
result << p
|
27
|
+
if p.kind == :element
|
28
|
+
p.node.substitutes.each do |s|
|
29
|
+
result << Particle.new(:element, [], p.minOccurs, p.maxOccurs, s)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
result
|
34
|
+
end
|
35
|
+
|
36
|
+
# flattens the particle tree with root +particle+ and calculates min/max occurrence
|
37
|
+
# returns a list of particles of kind "element" and "any"
|
38
|
+
# element names are unique throughout the list
|
39
|
+
# the order is the order of first occurrence
|
40
|
+
def flatten_particle_tree(particle)
|
41
|
+
if particle.kind == :element || particle.kind == :any
|
42
|
+
[particle]
|
43
|
+
else
|
44
|
+
eocc = {}
|
45
|
+
elist = []
|
46
|
+
particle.children.each do |c|
|
47
|
+
flatten_particle_tree(c).each do |e|
|
48
|
+
if e.kind == :element
|
49
|
+
name = e.node.name
|
50
|
+
else
|
51
|
+
name = "#any#"
|
52
|
+
end
|
53
|
+
if !eocc[name]
|
54
|
+
eocc[name] = []
|
55
|
+
elist << name
|
56
|
+
end
|
57
|
+
eocc[name] << e
|
58
|
+
end
|
59
|
+
end
|
60
|
+
is_unbounded = lambda do |particle, elements|
|
61
|
+
(particle.maxOccurs == "unbounded" &&
|
62
|
+
elements.any?{|e| e.maxOccurs == "unbounded" || e.maxOccurs.to_i > 0}) ||
|
63
|
+
(particle.maxOccurs.to_i > 0 &&
|
64
|
+
elements.any?{|e| e.maxOccurs == "unbounded"})
|
65
|
+
end
|
66
|
+
if particle.kind == :choice
|
67
|
+
elist.collect do |n|
|
68
|
+
if eocc[n].size < particle.children.size
|
69
|
+
# element is not in every choice
|
70
|
+
min = 0
|
71
|
+
else
|
72
|
+
min = eocc[n].collect{|e| e.minOccurs.to_i}.min * particle.minOccurs.to_i
|
73
|
+
end
|
74
|
+
if is_unbounded.call(particle, eocc[n])
|
75
|
+
max = "unbounded"
|
76
|
+
else
|
77
|
+
max = eocc[n].collect{|e| e.maxOccurs.to_i}.max * particle.maxOccurs.to_i
|
78
|
+
end
|
79
|
+
if n == "#any#"
|
80
|
+
Particle.new(:any, [], min, max, eocc[n].first.node)
|
81
|
+
else
|
82
|
+
Particle.new(:element, [], min, max, eocc[n].first.node)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
else # sequence or all
|
86
|
+
elist.collect do |n|
|
87
|
+
min = eocc[n].inject(0){|m, e| m + e.minOccurs.to_i} * particle.minOccurs.to_i
|
88
|
+
if is_unbounded.call(particle, eocc[n])
|
89
|
+
max = "unbounded"
|
90
|
+
else
|
91
|
+
max = eocc[n].inject(0){|m, e| m + e.maxOccurs.to_i} * particle.maxOccurs.to_i
|
92
|
+
end
|
93
|
+
if n == "#any#"
|
94
|
+
Particle.new(:any, [], min, max, eocc[n].first.node)
|
95
|
+
else
|
96
|
+
Particle.new(:element, [], min, max, eocc[n].first.node)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# builds the particle trees for the particles contained in node
|
104
|
+
def build_particles_trees(node)
|
105
|
+
trees = []
|
106
|
+
# ComplexType and extension type have only one choice, sequence, all, group
|
107
|
+
choices = node.choice
|
108
|
+
choices = [choices].compact unless choices.is_a?(Array)
|
109
|
+
choices.each do |c|
|
110
|
+
trees << Particle.new(:choice, build_particles_trees(c), c.minOccurs || "1", c.maxOccurs || "1", c)
|
111
|
+
end
|
112
|
+
sequences = node.sequence
|
113
|
+
sequences = [sequences].compact unless sequences.is_a?(Array)
|
114
|
+
sequences.each do |s|
|
115
|
+
trees << Particle.new(:sequence, build_particles_trees(s), s.minOccurs || "1", s.maxOccurs || "1", s)
|
116
|
+
end
|
117
|
+
alls = node.all
|
118
|
+
alls = [alls].compact unless alls.is_a?(Array)
|
119
|
+
alls.each do |a|
|
120
|
+
trees << Particle.new(:all, build_particles_trees(s), a.minOccurs || "1", a.maxOccurs || "1", a)
|
121
|
+
end
|
122
|
+
# Group definitions don't have group reference particles
|
123
|
+
if node.respond_to?(:group)
|
124
|
+
groups = node.group
|
125
|
+
groups = [groups].compact unless groups.is_a?(Array)
|
126
|
+
groups.each do |g|
|
127
|
+
if g.ref
|
128
|
+
# the referenced group is a Model Group Definition, i.e. a node wrapping a Model Group
|
129
|
+
# it must contain at most one of Choice, Sequence, All
|
130
|
+
# it must not contain another "group" tag because this would be a particle
|
131
|
+
group_childs = g.ref.all + g.ref.choice + g.ref.sequence
|
132
|
+
if group_childs.size == 1
|
133
|
+
gtc = build_particles_trees(g.ref).first
|
134
|
+
gtc.minOccurs = g.minOccurs || "1"
|
135
|
+
gtc.maxOccurs = g.maxOccurs || "1"
|
136
|
+
trees << gtc
|
137
|
+
elsif group_childs.size > 1
|
138
|
+
puts "WARN: ignoring model group definition containing more than one model group"
|
139
|
+
else
|
140
|
+
# empty, ignore
|
141
|
+
end
|
142
|
+
else
|
143
|
+
puts "WARN: ignoring non-toplevel group without a ref"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
# ComplexType and complex content extension don't have element particles
|
148
|
+
if node.respond_to?(:element)
|
149
|
+
node.element.each do |e|
|
150
|
+
if e.ref
|
151
|
+
trees << Particle.new(:element, [], e.minOccurs || "1", e.maxOccurs || "1", e.ref)
|
152
|
+
else
|
153
|
+
trees << Particle.new(:element, [], e.minOccurs || "1", e.maxOccurs || "1", e)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
# ComplexType and complex content extension don't have 'any' particles
|
158
|
+
if node.respond_to?(:any)
|
159
|
+
node.any.each do |a|
|
160
|
+
trees << Particle.new(:any, [], a.minOccurs || "1", a.maxOccurs || "1", a)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
trees
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module RGen
|
2
|
+
module XSD
|
3
|
+
module SimpleType
|
4
|
+
|
5
|
+
SimpleType = Struct.new(:type, :isList, :minOccurs, :maxOccurs)
|
6
|
+
|
7
|
+
def build_type_desc(type)
|
8
|
+
builtin = builtin_type(type)
|
9
|
+
if builtin
|
10
|
+
builtin
|
11
|
+
elsif type.respond_to?(:list) && type.list
|
12
|
+
if type.list.itemType || type.list.simpleType
|
13
|
+
td = build_type_desc(type.list.itemType || type.list.simpleType)
|
14
|
+
td.isList = true
|
15
|
+
td.minOccurs = 0
|
16
|
+
td.maxOccurs = -1
|
17
|
+
td
|
18
|
+
else
|
19
|
+
puts "WARN: list type without an item type"
|
20
|
+
SimpleType.new(:string, false, 0, 1)
|
21
|
+
end
|
22
|
+
elsif type.respond_to?(:union) && type.union
|
23
|
+
# TODO
|
24
|
+
# (type.union.memberTypes + type.union.simpleType).each do |t|
|
25
|
+
# build_type_desc(t)
|
26
|
+
# end
|
27
|
+
# TODO: make this a string instead? otherwise there is a problem serializing with RText (could also be fixed in RText: o.to_s)
|
28
|
+
SimpleType.new(:object, false, 0, 1)
|
29
|
+
elsif type.respond_to?(:restriction) && type.restriction
|
30
|
+
if type.restriction.base
|
31
|
+
td = build_type_desc(type.restriction.base)
|
32
|
+
if td.type == :string && type.restriction.enumeration.size > 0
|
33
|
+
SimpleType.new(
|
34
|
+
type.restriction.enumeration.collect { |e| e.value },
|
35
|
+
false, 0, 1)
|
36
|
+
elsif td.isList
|
37
|
+
# assumption: restrictions are properly nested
|
38
|
+
# note: this doesn't work correctly in case of lists of lists
|
39
|
+
td.minOccurs = type.restriction.minLength.first.value.to_i if type.restriction.minLength.first
|
40
|
+
td.maxOccurs = type.restriction.maxLength.first.value.to_i if type.restriction.maxLength.first
|
41
|
+
td
|
42
|
+
else
|
43
|
+
# unhandled restriction, pass the original
|
44
|
+
td
|
45
|
+
end
|
46
|
+
else
|
47
|
+
puts "WARN: restriction type without a base type"
|
48
|
+
SimpleType.new(:string, false, 0, 1)
|
49
|
+
end
|
50
|
+
else
|
51
|
+
puts "WARN: unknown node type: #{type.class}"
|
52
|
+
SimpleType.new(:string, false, 0, 1)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def builtin_type(type)
|
57
|
+
if type.nil?
|
58
|
+
# assumen anySimpleType
|
59
|
+
return SimpleType.new(:string, false, 0, 1)
|
60
|
+
end
|
61
|
+
case type.name
|
62
|
+
when "anyType"
|
63
|
+
SimpleType.new(:object, false, 0, 1)
|
64
|
+
when "anySimpleType", "string", "normalizedString", "token", "language", "Name", "NCName",
|
65
|
+
"ID", "IDREF", "ENTITY", "NMTOKEN", "base64Binary", "hexBinary", "anyURI", "QName",
|
66
|
+
"NOTATION", "duration", "dateTime", "time", "date", "gYearMonth", "gYear", "gMonthDay",
|
67
|
+
"gDay", "gMonth"
|
68
|
+
SimpleType.new(:string, false, 0, 1)
|
69
|
+
when "IDREFS", "ENTITIES", "NMTOKENS"
|
70
|
+
SimpleType.new(:string, true, 0, -1)
|
71
|
+
when "float", "double"
|
72
|
+
SimpleType.new(:float, false, 0, 1)
|
73
|
+
when "decimal", "integer", "nonPositiveInteger", "negativeInteger", "long", "int", "short",
|
74
|
+
"byte", "nonNegativeInteger", "unsignedLong", "unsignedInt", "unsignedShort",
|
75
|
+
"unsignedByte", "positiveInteger"
|
76
|
+
SimpleType.new(:int, false, 0, 1)
|
77
|
+
when "boolean"
|
78
|
+
SimpleType.new(:boolean, false, 0, 1)
|
79
|
+
else
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
@@ -0,0 +1,6 @@
|
|
1
|
+
This folder contains the following schema parts as published by the W3C
|
2
|
+
|
3
|
+
* xml.xsd (http://www.w3.org/2007/08/xml.xsd)
|
4
|
+
|
5
|
+
Copyright � 2007 World Wide Web Consortium, (Massachusetts Institute of Technology, European Research Consortium for Informatics and Mathematics, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/2002/copyright-documents-20021231
|
6
|
+
|
@@ -0,0 +1,145 @@
|
|
1
|
+
<?xml version='1.0'?>
|
2
|
+
<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="en">
|
3
|
+
|
4
|
+
<xs:annotation>
|
5
|
+
<xs:documentation>
|
6
|
+
See http://www.w3.org/XML/1998/namespace.html and
|
7
|
+
http://www.w3.org/TR/REC-xml for information about this namespace.
|
8
|
+
|
9
|
+
This schema document describes the XML namespace, in a form
|
10
|
+
suitable for import by other schema documents.
|
11
|
+
|
12
|
+
Note that local names in this namespace are intended to be defined
|
13
|
+
only by the World Wide Web Consortium or its subgroups. The
|
14
|
+
following names are currently defined in this namespace and should
|
15
|
+
not be used with conflicting semantics by any Working Group,
|
16
|
+
specification, or document instance:
|
17
|
+
|
18
|
+
base (as an attribute name): denotes an attribute whose value
|
19
|
+
provides a URI to be used as the base for interpreting any
|
20
|
+
relative URIs in the scope of the element on which it
|
21
|
+
appears; its value is inherited. This name is reserved
|
22
|
+
by virtue of its definition in the XML Base specification.
|
23
|
+
|
24
|
+
id (as an attribute name): denotes an attribute whose value
|
25
|
+
should be interpreted as if declared to be of type ID.
|
26
|
+
This name is reserved by virtue of its definition in the
|
27
|
+
xml:id specification.
|
28
|
+
|
29
|
+
lang (as an attribute name): denotes an attribute whose value
|
30
|
+
is a language code for the natural language of the content of
|
31
|
+
any element; its value is inherited. This name is reserved
|
32
|
+
by virtue of its definition in the XML specification.
|
33
|
+
|
34
|
+
space (as an attribute name): denotes an attribute whose
|
35
|
+
value is a keyword indicating what whitespace processing
|
36
|
+
discipline is intended for the content of the element; its
|
37
|
+
value is inherited. This name is reserved by virtue of its
|
38
|
+
definition in the XML specification.
|
39
|
+
|
40
|
+
Father (in any context at all): denotes Jon Bosak, the chair of
|
41
|
+
the original XML Working Group. This name is reserved by
|
42
|
+
the following decision of the W3C XML Plenary and
|
43
|
+
XML Coordination groups:
|
44
|
+
|
45
|
+
In appreciation for his vision, leadership and dedication
|
46
|
+
the W3C XML Plenary on this 10th day of February, 2000
|
47
|
+
reserves for Jon Bosak in perpetuity the XML name
|
48
|
+
xml:Father
|
49
|
+
</xs:documentation>
|
50
|
+
</xs:annotation>
|
51
|
+
|
52
|
+
<xs:annotation>
|
53
|
+
<xs:documentation>This schema defines attributes and an attribute group
|
54
|
+
suitable for use by
|
55
|
+
schemas wishing to allow xml:base, xml:lang, xml:space or xml:id
|
56
|
+
attributes on elements they define.
|
57
|
+
|
58
|
+
To enable this, such a schema must import this schema
|
59
|
+
for the XML namespace, e.g. as follows:
|
60
|
+
<schema . . .>
|
61
|
+
. . .
|
62
|
+
<import namespace="http://www.w3.org/XML/1998/namespace"
|
63
|
+
schemaLocation="http://www.w3.org/2001/xml.xsd"/>
|
64
|
+
|
65
|
+
Subsequently, qualified reference to any of the attributes
|
66
|
+
or the group defined below will have the desired effect, e.g.
|
67
|
+
|
68
|
+
<type . . .>
|
69
|
+
. . .
|
70
|
+
<attributeGroup ref="xml:specialAttrs"/>
|
71
|
+
|
72
|
+
will define a type which will schema-validate an instance
|
73
|
+
element with any of those attributes</xs:documentation>
|
74
|
+
</xs:annotation>
|
75
|
+
|
76
|
+
<xs:annotation>
|
77
|
+
<xs:documentation>In keeping with the XML Schema WG's standard versioning
|
78
|
+
policy, this schema document will persist at
|
79
|
+
http://www.w3.org/2007/08/xml.xsd.
|
80
|
+
At the date of issue it can also be found at
|
81
|
+
http://www.w3.org/2001/xml.xsd.
|
82
|
+
The schema document at that URI may however change in the future,
|
83
|
+
in order to remain compatible with the latest version of XML Schema
|
84
|
+
itself, or with the XML namespace itself. In other words, if the XML
|
85
|
+
Schema or XML namespaces change, the version of this document at
|
86
|
+
http://www.w3.org/2001/xml.xsd will change
|
87
|
+
accordingly; the version at
|
88
|
+
http://www.w3.org/2007/08/xml.xsd will not change.
|
89
|
+
</xs:documentation>
|
90
|
+
</xs:annotation>
|
91
|
+
|
92
|
+
<xs:attribute name="lang">
|
93
|
+
<xs:annotation>
|
94
|
+
<xs:documentation>Attempting to install the relevant ISO 2- and 3-letter
|
95
|
+
codes as the enumerated possible values is probably never
|
96
|
+
going to be a realistic possibility. See
|
97
|
+
RFC 3066 at http://www.ietf.org/rfc/rfc3066.txt and the IANA registry
|
98
|
+
at http://www.iana.org/assignments/lang-tag-apps.htm for
|
99
|
+
further information.
|
100
|
+
|
101
|
+
The union allows for the 'un-declaration' of xml:lang with
|
102
|
+
the empty string.</xs:documentation>
|
103
|
+
</xs:annotation>
|
104
|
+
<xs:simpleType>
|
105
|
+
<xs:union memberTypes="xs:language">
|
106
|
+
<xs:simpleType>
|
107
|
+
<xs:restriction base="xs:string">
|
108
|
+
<xs:enumeration value=""/>
|
109
|
+
</xs:restriction>
|
110
|
+
</xs:simpleType>
|
111
|
+
</xs:union>
|
112
|
+
</xs:simpleType>
|
113
|
+
</xs:attribute>
|
114
|
+
|
115
|
+
<xs:attribute name="space">
|
116
|
+
<xs:simpleType>
|
117
|
+
<xs:restriction base="xs:NCName">
|
118
|
+
<xs:enumeration value="default"/>
|
119
|
+
<xs:enumeration value="preserve"/>
|
120
|
+
</xs:restriction>
|
121
|
+
</xs:simpleType>
|
122
|
+
</xs:attribute>
|
123
|
+
|
124
|
+
<xs:attribute name="base" type="xs:anyURI">
|
125
|
+
<xs:annotation>
|
126
|
+
<xs:documentation>See http://www.w3.org/TR/xmlbase/ for
|
127
|
+
information about this attribute.</xs:documentation>
|
128
|
+
</xs:annotation>
|
129
|
+
</xs:attribute>
|
130
|
+
|
131
|
+
<xs:attribute name="id" type="xs:ID">
|
132
|
+
<xs:annotation>
|
133
|
+
<xs:documentation>See http://www.w3.org/TR/xml-id/ for
|
134
|
+
information about this attribute.</xs:documentation>
|
135
|
+
</xs:annotation>
|
136
|
+
</xs:attribute>
|
137
|
+
|
138
|
+
<xs:attributeGroup name="specialAttrs">
|
139
|
+
<xs:attribute ref="xml:base"/>
|
140
|
+
<xs:attribute ref="xml:lang"/>
|
141
|
+
<xs:attribute ref="xml:space"/>
|
142
|
+
<xs:attribute ref="xml:id"/>
|
143
|
+
</xs:attributeGroup>
|
144
|
+
|
145
|
+
</xs:schema>
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module XMLSchemaMetamodel
|
2
|
+
|
3
|
+
module Element::ClassModule
|
4
|
+
def effectiveElement
|
5
|
+
ref || self
|
6
|
+
end
|
7
|
+
def effectiveType
|
8
|
+
e = effectiveElement
|
9
|
+
if e.getType && e.complexType
|
10
|
+
puts "WARN: element has both, a type reference and a contained type"
|
11
|
+
end
|
12
|
+
e.getType || e.complexType || e.simpleType
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module Attribute::ClassModule
|
17
|
+
def effectiveAttribute
|
18
|
+
ref || self
|
19
|
+
end
|
20
|
+
def effectiveType
|
21
|
+
e = effectiveAttribute
|
22
|
+
if e.getType && e.simpleType
|
23
|
+
puts "WARN: attribute has both, a type reference and a contained type"
|
24
|
+
end
|
25
|
+
e.getType || e.simpleType
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module ComplexType::ClassModule
|
30
|
+
def allAttributes
|
31
|
+
attribute + attributeGroup.allAttributes +
|
32
|
+
(complexContent.andand.extension.andand.allAttributes || []) +
|
33
|
+
(simpleContent.andand.extension.andand.allAttributes || [])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module ExtensionType::ClassModule
|
38
|
+
def allAttributes
|
39
|
+
attribute + attributeGroup.allAttributes
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
module AttributeGroup::ClassModule
|
44
|
+
def effectiveAttributeGroup
|
45
|
+
ref || self
|
46
|
+
end
|
47
|
+
def allAttributes
|
48
|
+
effectiveAttributeGroup.attribute
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
|