How to define an 'any element' with mandatory attributes - xsd

I have an XML which can have any element such as:
<AnyElements>
<Any1 id="any1" />
<Any2 id="any2" />
...
</AnyElements>
But id attribute is mandatory.
How can i define such a xsd?
<xs:element name="AnyElements" type="AnyRootType" />
<xs:complexType name="AnyRootType">
<xs:sequence>
<xs:any type="AnyChildType" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="AnyChildType">
<xs:attribute ref="id" use="required"/>
</xs:complexType>
<xs:attribute name="id" type="xs:string"/>

It all depends on how you're going to define the processing model. Here are some things you need to consider first.
An any particle can't be constrained with a type. It comes with an attribute named processContents that could be skip, lax, and the default, strict. Once you understand exactly what it means, then going with skip simply means that you will not be able to enforce your mandatory attribute - the processor will do just that, "skip". If you set it lax, then it will process it only if the XSD describing the content is actually available, otherwise it'll skip; The third option strict, requires the XSD describing this extra content to be available - period.
So the any particle can be made to work only if the XSD describing the "any" is available during validation. The option I have in mind is kind of limiting, but it has the advantage of being the closest to the "spirit" of an any in that it wouldn't have to derive from a particular base type, or reference some atttributes; for this, a key constraint similar to would approximate your requirement:
<xsd:key name="ofid">
<xsd:selector xpath="*"/>
<xsd:field xpath="#id"/>
</xsd:key>
In effect, the key makes the attribute required. The downside may be that each value must be unique, too. Maybe with an attribute named id , it is expected; if instead you wish to apply the pattern to something such as age, then it wouldn't work.
If you decide that having XSDs available at runtime is acceptable, then other alternatives may include use of abstract elements or elements with abstract types. The good thing is that it'll bring a more disciplined approach (you'll set the constraints clearly right from the beginning), and without placing uniqueness of values constraints. The downside could be that it creates coupling to another XSD which describes the "contract" - your mandatory attributes.
UPDATE: As per your comment, below is an alternative based on substitution groups. I tried to keep as much as possible your old XSD components names.
Contract.xsd: This has the components of your contract. It basically describes the head of your substitution group; it indicates the need for an id attribute.
<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="AnyChildType" abstract="true">
<xsd:attribute name="id" use="required"/>
</xsd:complexType>
<xsd:element name="AnyElement" abstract="true" type="AnyChildType"/>
</xsd:schema>
GenericInstance.xsd: It describes the root of your "generic" document. It "integrates" your contract in the context of your defined root element.
<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:include schemaLocation="Contract.xsd"/>
<xsd:element name="AnyElements" type="AnyRootType"/>
<xsd:complexType name="AnyRootType">
<xsd:sequence>
<xsd:element ref="AnyElement" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
SpecificInstance1.xsd: A particular contract.
<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:include schemaLocation="Contract.xsd"/>
<xsd:element name="SomeElement1" substitutionGroup="AnyElement">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="AnyChildType">
<xsd:annotation>
<xsd:documentation>Any content goes.</xsd:documentation>
</xsd:annotation>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
SpecificInstance2.xsd: Another contract (shows a different authoring style).
<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:include schemaLocation="Contract.xsd"/>
<xsd:element name="SomeElement2" substitutionGroup="AnyElement" type="SomeElement2Type"/>
<xsd:complexType name="SomeElement2Type">
<xsd:complexContent>
<xsd:extension base="AnyChildType">
<xsd:annotation>
<xsd:documentation>Any content goes.</xsd:documentation>
</xsd:annotation>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
Visually this is how they're tied together. You can see that the coupling between XSDs is maintained at minimum.
A sample XML, valid in the scope defined by your generic instance, and the specific ones.
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<AnyElements xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SomeElement1 id="1"/>
<SomeElement2 id="1"/>
</AnyElements>
If you're limited to validate your XML using one XSD only, below would be an XSD just for that:
<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:include schemaLocation="GenericInstance.xsd"/>
<xsd:include schemaLocation="SpecificInstance1.xsd"/>
<xsd:include schemaLocation="SpecificInstance2.xsd"/>
</xsd:schema>
I've tested the above with XSD 1.0 running on .NET; having the ability to run on XSD 1.1 or particular features in other XSD processors would invalidate some of what I've said.

Related

Unmarshalling xsd with selective element replacement from another xsd

I am new to working with xsd and jaxb, so if my questions are ignorant, please educate me. Also, if you need any more info, let me know and I will provide what I can.
At our company we are working with xsd sources from a 3rd party. We need to implement a SOAP - Java translation and we have a bunch of .wsdl and .xsd files to work with. We are running into problems with two of the .xsd files. The 3rd party provides a "datatypes.xsd", with a org.hl7.v3 namespace and a "datatypes-extensions-hl7nl.xsd", with a nl.hl7.v3 namespace.
When I unmarshall the xds sources, the resultant .java files get created under a different package, named after their own namespaces: org/hl7/v3 and nl/hl7/v3.
Whereas the 3rd party has intended that, where applicable, the types from "datatypes-extensions.xsd" have precedence and should be generated instead of those in "datatypes.xsd", and in the same package.
What I have tried so far
Since I cannot alter the xsd sources, I have (unsuccessfully) tried 2 things using a .jxb file.
1: generating the .java files in a single directory. This led to overwriting issues.
2: providing a binding to point to the correct type:
<jaxb:bindings schemaLocation="../coreschemas/datatypes.xsd">
<jaxb:bindings node="//xs:complexType[#name='TEL']">
<jaxb:class ref="nl.hl7.v3.TEL"/>
</jaxb:bindings>
</jaxb:bindings>
This worked initially, until I changed the reference of a supertype, at which point the compiler complained it could no longer locate the proper supertype for the extending types.
Sources
The sources are opensource so if you'd like to see them for yourself: https://decor.nictiz.nl/pub/vzvz/kz-vzvz-xml-20190122T131422.zip
The .wsdl:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:hl7="urn:hl7-org:v3"
targetNamespace="urn:hl7-org:v3"
name="OpvragenOverdrachtconcerns">
<documentation> WSDL implementatie van OpvragenOverdrachtconcerns</documentation>
<types>
<xsd:schema targetNamespace="urn:hl7-org:v3" elementFormDefault="qualified">
<xsd:include schemaLocation="../schemas_codeGen/REPC_IN990110NL.xsd"/>
</xsd:schema>
<xsd:schema targetNamespace="urn:hl7-org:v3" elementFormDefault="qualified">
<xsd:include schemaLocation="../schemas_codeGen/REPC_IN990111NL.xsd"/>
</xsd:schema>
</types>
<message name="REPC_IN990110NL">
<part name="body" element="hl7:REPC_IN990110NL"/>
</message>
<message name="REPC_IN990111NL">
<part name="body" element="hl7:REPC_IN990111NL"/>
</message>
The header of response message type: REPC_IN990111NL:
<?xml version="1.0" encoding="UTF-8"?>
<!-- REPC_IN990111NL - Opleveren overdrachtconcerns --><!--Note: this file was generated. DO NOT EDIT HERE.--><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="urn:hl7-org:v3"
targetNamespace="urn:hl7-org:v3"
elementFormDefault="qualified">
The header and definition of a conflicting type in datatypes.xsd:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:hl7="urn:hl7-org:v3" xmlns:hl7nl="urn:hl7-nl:v3"
xmlns:sch="http://www.ascc.net/xml/schematron" elementFormDefault="qualified" targetNamespace="urn:hl7-org:v3" xmlns="urn:hl7-org:v3">
<xsd:include schemaLocation="voc.xsd"/>
<xsd:import namespace="urn:hl7-nl:v3" schemaLocation="datatypes-extensions-hl7nl.xsd"/>
<xsd:complexType name="TEL">
<xsd:complexContent>
<xsd:extension base="URL">
<xsd:sequence>
<xsd:element name="useablePeriod" type="IVL_TS" minOccurs="0"
maxOccurs="unbounded">
<!-- FIXME: one would expect the name "GTS" here but it's not
SXCM does ALL the right things, it's just not the right NAME. -->
</xsd:element>
<xsd:element name="id" type="II" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="use" type="set_cs_TelecommunicationAddressUse" use="optional">
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
The header and type in datatypes-extension-hl7nl.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns:hl7="urn:hl7-org:v3" xmlns="urn:hl7-nl:v3" xmlns:sch="http://purl.oclc.org/dsdl/schematron" targetNamespace="urn:hl7-nl:v3">
<xsd:import schemaLocation="datatypes.xsd" namespace="urn:hl7-org:v3"/>
<xsd:complexType name="TEL">
<xsd:complexContent>
<xsd:extension base="ANY">
<xsd:sequence>
<xsd:element name="useablePeriod" type="QSET_TS" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="value" type="xsd:anyURI" use="optional"/>
<xsd:attribute name="use" type="set_TelecommunicationAddressUse" use="optional"/>
<xsd:attribute name="capabilities" type="set_TelecommunicationCapability" use="optional"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
Expected and actual results
As stated above, instead of generating two packages according to the different namespaces, one should be created with the "nl.hl7.v3" types being generated intead of the "org.hl7.v3" ones with the same name.
Thank you for your time in advance.
Max

XSD namespace "ns2" issue

I have schema defined in Request.xsd which will refer common.xsd.
I'm expecting the output should come as below
<Request xmlns="http://ws.myref.com/schemas/test"
xmlns="http://ps.myref.com/schemas/2008/Common">
<EmailList>
<Mail>test#gmail.com</Mmail>
</EmailList>
</Request>
But i'm getting extra namespace "ns2" issue. Can anybody help me out to resolve this issue
<ns2:Request xmlns:ns2="http://ps.myref.com/schemas/test"
xmlns="http://ps.myref.com/schemas/Common">
<ns2:EmailList>
<Mail>test#gmail.com</Mail>
</ns2:EmailList>
</ns2:Request>
Request.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" targetNamespace="http://ps.myref.com/schemas/schemas/test"
xmlns="http://ps.myref.com/schemas/schemas/test" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:com="http://ps.myref.com/schemas/Common">
<xsd:import namespace="http://ps.myref.com/schemas/Common" schemaLocation="../schemas/common/common.xsd"/>
<xsd:element name="Request">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="EmailLists" type="com:EmailList" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Common.xsd
<?xml version="1.0"?>
<xsd:schema xmlns="http://ps.myref.com/schemas/2008/Common" elementFormDefault="unqualified"
targetNamespace="http://ps.myref.com/schemas/Common"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsd:complexType name="EmailList">
<xsd:sequence>
<xsd:element name="Mail" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Your expectation is unreasonable in this instance.
Because the type "EmailList" is defined under the namespace http://ps.myref.com/schemas/2008/Common in the common.xsd file, you have no option but to differentiate it in some way when you use the EmailList type in another schema. If you look at request.xsd, you can see that this is exectyly what happens here:
<xsd:element name="EmailLists" type="com:EmailList" />
The com: in this case is a prefix designed to show that the type is defined in another schema and under a different namespace to the one being used.
In the same way, when the xsd validator uses the request.xsd to validate a schema instance, it has to ensure that the EmailList type you are using in your instance is the same EmailList type which is defined in the common.xsd schema, and the only way it can do that is by using the namespace.
Your expectation can therefore be summarized thus:
"I should be able to mix types defined in two different schema definitions freely together without differentiating them and the parser should understand that."
So you should be able to see now how your expectation does not make logical sense.
If you don't want the "ns2:" in there, your only other alternative is to do this:
<Request xmlns"http://ps.myref.com/schemas/test">
<EmailList xmlns"http://ps.myref.com/schemas/test">
<Mail xmlns="http://ps.myref.com/schemas/Common">test#gmail.com</Mail>
</EmailList>
</Request>

use type from xsd imported from import

Given a top level xsd that imports a second level which in turn imports a third, is it possible to use a type from the third in the first? Or does the first have to import the third directly?
Good question!
From reading the spec, I can't really tell. It doesn't explicitly address the issue of transitive imports explicitly.
In the Primer (part 0), they only talk about one level of importing: http://www.w3.org/TR/xmlschema-0/#import
In Structure (part 1), it also only defines direct importing http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#composition-schemaImport Since it talks about "a means of addressing such foreign component" (which I think means namespace), maybe it's reasonable to assume that an explicit way of addressing imported schemas is necessary - in other words, an explicit namespace in an import is needed for each one.
A google search shows that other people have also been confused by this issue:
http://xsd.stylusstudio.com/2002Apr/post00021.htm
http://xsd.stylusstudio.com/2005Mar/post05007.htm
What's of most concern about those posts is that different xsd processors have different behaviour - suggesting that the writers of the processors were also confused.
Although that may have changed since those posts (2002, 2005), the wisest course seems to be to avoid the issue, and just use direct imports, because this will work with all processors.
As I said: good question.
Here is a test, to check an xsd processor (of course, this won't guarantee that it will work for someone else using some other xsd processor...). I found that my favourite one (xmllint) does not allow transitive imports.
The test is three schemas: a.xsd imports b.xsd which in turn imports c.xsd; and a type defined in c.xsd is referenced from a.xsd:
<!-- a.xsd -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:c="http://www.c.com" targetNamespace="http://www.a.com">
<xsd:import namespace="http://www.b.com" schemaLocation="b.xsd"/>
<!-- UNCOMMENT FOR DIRECT IMPORT
<xsd:import namespace="http://www.c.com" schemaLocation="c.xsd"/>
-->
<xsd:element name="eg" type="c:TypeC"/>
</xsd:schema>
<!-- b.xsd -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:import namespace="http://www.c.com" schemaLocation="c.xsd"/>
</xsd:schema>
<!-- c.xsd -->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.c.com">
<xsd:simpleType name="TypeC">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
</xsd:schema>
<!-- a.xml -->
<eg xmlns="http://www.a.com">hello world</eg>
$ xmllint --schema a.xsd a.xml --noout
a.xsd:6: element element: Schemas parser error : Element
'{http://www.w3.org/2001/XMLSchema}element', attribute 'type': References from
this schema to components in the namespace 'http://www.c.com' are not allowed,
since not indicated by an import statement.
WXS schema a.xsd failed to compile
The error message is: References from this schema to components in the namespace 'http://www.c.com' are not allowed, since not indicated by an import statement., suggesting that the developers of xmllint at least are quite sure that imports are not transitive.
If type is what you are talking about then .. It's <xs:Include> not <xs:Import> ..
And the answer is : Parser takes care of linking all XSDs together
see the example below:
<?xml version="1.0" encoding="utf-8"?>
<root>
<child>trial</child>
<child2>trial2</child2>
<trunk>
<branch>1</branch>
<branch>2</branch>
</trunk>
<specialchild>test</specialchild>
</root>
For the above XML I will design an XSD:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="include multiple XSDs2.xsd"/>
<xs:element name="root" type ="root"/>
<xs:complexType name="root">
<xs:sequence>
<xs:element name="child" type="xs:string" />
<xs:element name="child2" type="xs:string" />
<xs:element name="trunk" type="trunk"/>
<xs:element name="specialchild" type="specialchild"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
where type trunk is defined in import multiple XSDs2.xsd file and linked by using <xs:include> .. (which is residing in the same folder).. And the code looks like this:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="include multiple XSDs3.xsd"/>
<xs:complexType name="trunk">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="branch" type="branch" />
</xs:sequence>
</xs:complexType>
</xs:schema>
and type branch is a simple type defined in include multiple XSDs3.xsd file, and the code looks like this:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="branch">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="specialchild">
<xs:restriction base="xs:string"/>
</xs:simpleType>
</xs:schema>
*Now the tricky part is: specialchild is declared in XSD_1 where as defined in XSD_3 and these two XSDs are linked by XSD_2..
You can observe that parser by default takes care of linking all XSDs and treating them all as one! *
Hope this solves your question!

Xml Schema with AnyAttribute, add attribute to specific element

If I have two elements with the <anyattribute/> element in my schema like this:
<xs:element name="NodeType1">
<xs:complexType>
<xs:anyAttribute />
</xs:complexType>
</xs:element>
<xs:element name="NodeType2">
<xs:complexType>
<xs:anyAttribute />
</xs:complexType>
</xs:element>
Is it possible to extend only one of those elements in another schema? Let's say I wanted to add an attribute to NodeType2 only.
Elements are not extensible; in general, you will have to create a named (global, under the schema element) type if you wish to use as a base for extension anywhere else, be that in the same or another XML Schema.
Your question is very interesting because it really makes one wonder what is the purpose of extending something that by definition could match anything, anyhow. For that, the effect of the extension is really the opposite; it creates a constraint for the attribute(s) named in the extension.
So, the first XSD:
<?xml version="1.0" encoding="utf-8" ?>
<!--W3C Schema generated by QTAssistant/W3C Schema Refactoring Module (http://www.paschidev.com)-->
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/XMLSchema.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="root" type="BaseType"/>
<xsd:complexType name="BaseType">
<xsd:anyAttribute processContents="lax" />
</xsd:complexType>
<xsd:complexType name="Extending">
<xsd:complexContent>
<xsd:extension base="BaseType">
<xsd:attribute name="new1" type="xsd:int"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
With this schema, the following sample XML is perfectly valid:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" new1="S" new2="2" xmlns="http://tempuri.org/XMLSchema.xsd"/>
Now, if I'm changing
<xsd:element name="root" type="BaseType"/>
to
<xsd:element name="root" type="Extending"/>
the same sample XML if no longer valid:
Error occurred while loading [], line 3 position 61
The 'new1' attribute is invalid - The value 'S' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:int' - The string 'S' is not a valid Int32 value.
Changing the S to a numeric, it will make the XML valid.
Isn't that a funny thing about "extending"?...

Are circular groups allowed by XSD schema?

For this xml:
<elem1 xmlns="http://www.fixprotocol.org/ns/fast/t/1.0">
<elem2>
<elem2/>
</elem2>
</elem1>
I have this schema, which seems to validate fine against w3 schema validation service, and the schema validates the above XML just fine. Sadly, xsd.exe and some other tools report it to be an error. Is that correct? Are circular group refs dissallowed by XML schema? Thanks!
Update: The schema is not mine, can't change it :(
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.fixprotocol.org/ns/fast/t/1.0" xmlns:t="http://www.fixprotocol.org/ns/fast/t/1.0">
<xs:element name="elem1">
<xs:complexType>
<xs:group ref="t:grp1" />
</xs:complexType>
</xs:element>
<xs:group name="grp1">
<xs:sequence>
<xs:group ref="t:grp2" />
</xs:sequence>
</xs:group>
<xs:group name="grp2">
<xs:sequence>
<xs:element minOccurs="0" name="elem2">
<xs:complexType>
<xs:group ref="t:grp1" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:group>
</xs:schema>
It's a legal scheme. Problem is that xsd is trying to traverse all dependencies. The MS version preprocesses scheme and expands all groups. Because of the cyclic dependency such expansion would be infinite so it quits with an error. With the Mono version there are two probable scenarios:
It tries to traverse dependency tree
and ends up in an infinite loop.
It tries to expand all groups and
ends up in an infinite loop.
That is just my guess. I never saw actual source codes of Mono xsd.
This question is being linked with many recent questions that talk about the same problem: circular groups, and Microsoft's xsd.exe, hence I think it should be answered, even though it is quite "old".
The confusion is caused by what qualifies as a circular group. According to section 3.8.6 of the XSD spec:
"Circular groups are disallowed. That is, within the {particles} of a
group there must not be at any depth a particle whose {term} is the
group itself."
Based on the above, your example is not a circular group, since the group itself does not rely on itself as a particle. Your schema is valid.
This is a circular group:
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns="http://www.fixprotocol.org/ns/fast/t/1.0" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.fixprotocol.org/ns/fast/t/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="elem1">
<xsd:complexType>
<xsd:group ref="grp1"/>
</xsd:complexType>
</xsd:element>
<xsd:group name="grp1">
<xsd:sequence>
<xsd:choice>
<xsd:group ref="grp1"/>
</xsd:choice>
</xsd:sequence>
</xsd:group>
</xsd:schema>
One cannot rewrite a true circular group. However, your example can be rewritten in a couple of ways: the schema below shows an equivalent content model, based on recursive complex types.
<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema xmlns="http://www.fixprotocol.org/ns/fast/t/1.0" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.fixprotocol.org/ns/fast/t/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xmlns="">Generated from "Set1" under "Release2"</xsd:documentation>
</xsd:annotation>
<xsd:complexType name="grp1">
<xsd:sequence>
<xsd:element minOccurs="0" name="elem2" type="grp1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="elem1" type="grp1"/>
</xsd:schema>
It is also "entertaining" to see that the following schema actually works with xsd.exe:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema xmlns="http://www.fixprotocol.org/ns/fast/t/1.0" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.fixprotocol.org/ns/fast/t/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xmlns="">Generated from "Set1" under "Release2"</xsd:documentation>
</xsd:annotation>
<xsd:element name="elem1">
<xsd:complexType>
<xsd:group ref="grp1"/>
</xsd:complexType>
</xsd:element>
<xsd:group name="grp1">
<xsd:sequence>
<xsd:element minOccurs="0" name="elem2">
<xsd:complexType>
<xsd:group ref="grp1"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:group>
</xsd:schema>
From an XML instance perspective, all three valid schemas are equivalent.
The issue is probably that the tools you are using don't support all possibilities supported by the XML schema spec. Certainly xsd.exe doesn't support everything. The spec is gigantic and it isn't worth providing mappings from everything it supports into a programming language, particularly when some things just don't map very well.
To work around this, you could try to create a set of C# classes that mimic the xml you want to generate and then run xsd.exe on those classes to generate an xsd. There is probably some other XML schema construct that supports what you want.
I don't know about groups but XSD.exe supports circular elements:
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Class1" nillable="true" type="Class1" />
<xs:complexType name="Class1">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Name" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="child" type="Class1" />
</xs:sequence>
</xs:complexType>
</xs:schema>

Resources