Open ronaldtse opened 2 months ago
This is urgently needed for:
This is urgently needed for:
@ronaldtse I'm working on it
@HassanAkbar and there is an XSD Schema for XSD itself:
We can use Lutaml::Model to parse XSD schemas.
Thanks @HassanAkbar, this is how Shale works:
Given an (one or more) XSD schema:
require 'shale'
require 'shale/schema'
schema1 = <<~SCHEMA
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:bar="http://bar.com"
elementFormDefault="qualified"
>
<xs:import namespace="http://bar.com" />
<xs:element name="Person" type="Person" />
<xs:complexType name="Person">
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element ref="bar:Address" />
</xs:sequence>
</xs:complexType>
</xs:schema>
SCHEMA
schema2 = <<~SCHEMA
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:bar="http://bar.com"
targetNamespace="http://bar.com"
elementFormDefault="qualified"
>
<xs:element name="Address" type="bar:Address" />
<xs:complexType name="Address">
<xs:sequence>
<xs:element name="Street" type="xs:string" />
<xs:element name="City" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
SCHEMA
mapping = {
nil => 'Api::Foo', # no namespace
'http://bar.com' => 'Api::Bar',
}
result = Shale::Schema.from_xml(
[schema1, schema2],
namespace_mapping: mapping
)
result.each do |name, model|
puts "# ----- #{name}.rb -----"
puts model
end
The output is:
# ----- api/bar/address.rb -----
require 'shale'
module Api
module Bar
class Address < Shale::Mapper
attribute :street, Shale::Type::String
attribute :city, Shale::Type::String
xml do
root 'Address'
namespace 'http://bar.com', 'bar'
map_element 'Street', to: :street
map_element 'City', to: :city
end
end
end
end
# ----- api/foo/person.rb -----
require 'shale'
require_relative '../bar/address'
module Api
module Foo
class Person < Shale::Mapper
attribute :name, Shale::Type::String
attribute :address, Api::Bar::Address
xml do
root 'Person'
map_element 'Name', to: :name
map_element 'Address', to: :address, prefix: 'bar', namespace: 'http://bar.com'
end
end
end
end
We don't need to print it out, instead, we want to create those files directly with code.
This functionality is called "compile" in Shale, where it generates Shale classes in Ruby source code for a given XSD.
We can do the following:
lib/xxx/*.rb
structure, wherexxx
is a configurable namespace (kind of like thebundle gem {name}
command)