I want to convert the following schema from RNC/RNG to W3C XSD.
default namespace = ""
namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0"
namespace rng = "http://relaxng.org/ns/structure/1.0"
start = starting_risk
starting_risk =
element risk {
element continents { Continents }?
}
Continents = element continent { Continent }+
Continent =
element country { Country }*,
element sea { Sea }*
Country = xsd:string { minLength = "1" maxLength = "100" }
Sea = xsd:string { minLength = "1" maxLength = "100" }
Using trang, I end up with
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="risk">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" ref="continents"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="continents" type="Continents"/>
<xs:complexType name="Continents">
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="continent"/>
</xs:sequence>
</xs:complexType>
<xs:element name="continent" type="Continent"/>
<xs:complexType name="Continent">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="country"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="sea"/>
</xs:sequence>
</xs:complexType>
<xs:element name="country" type="Country"/>
<xs:element name="sea" type="Sea"/>
<xs:simpleType name="Country">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="100"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Sea">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="100"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
The problem is that the hierarchy is lost. The 'risk' element is the root of the schema and the only valid element at that level. In the RNC, the relationship between 'risk' and 'continent' elements is parent to child. But in the XSD, they are siblings. What am I doing wrong/ have I not understood?
You’re not doing anything wrong. I think unfortunately you just can’t use
trang
to generate an XSD from your RNC schema that preserves the restriction on what’s allowed as the root element.You could instead manually create an XSD restricted to having
risk
be the only global element, with all the rest of the elements each being a local element. But (as far as I know) you can’t generate such an XSD usingtrang
. The reason is that (again, as far as I know at least)trang
basically always generates XSDs only with global elements.You might think you could generate an XSD with local elements if you wrote your RNC like this:
That’s basically structured in the same way you’d want to structure your XSD if you did it manually.
But if you run that through
trang
to generate an XSD, you’ll find that every single element comes out as a global element in the resulting XSD. That’s just howtrang
always does it.So unless there’s some magic way I’m unaware of to force
trang
to do otherwise, your only alternative if you want to restrict your XSD schema to only havingrisk
allowed as the root element is, create the XSD manually.I guess that could be seen as a design flaw in
trang
, but arguably the real problem is that XML Schema by design has nothing similar to RelaxNG’sstart
to explicitly specify a root element.If XML Schema did have a similar simple way like RelaxNG’s
start
to specify what’s allowed as the root element, thentrang
could just output that in the XSD and you’d have what you want.But because XSD has nothing like
start
, your only mechanism for restricting your schema to having only one particular root element is to completely (re)structure your XSD into the “local style”.However, as mentioned earlier in this answer, you unfortunately can’t generate such a “local style” XSD from RelaxNG sources using
trang
. You instead must separately create the XSD manually.It’s imaginable
trang
ideally could have been designed with some option to allow you to generate “local style” XSDs or maybe with some heuristics to somehow infer when that’s the output style it should use. But the reality is, that’s not the waytrang
actually works, and it’s not going to change.So while I’m sure that isn’t the answer you were hoping to get, I hope it helps clarify things.