I have a XML and a corresponding XSD as follows:
myXSD.xsd :
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com/myXSD"
xmlns="http://www.example.com/myXSD"
elementFormDefault="qualified">
<xs:element name="RootElem">
<xs:complexType>
<xs:sequence>
<xs:element name="Insider1">
<xs:complexType>
<xs:sequence>
<xs:element ref="Internal" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Insider2">
<xs:complexType>
<xs:sequence>
<xs:element ref="Internal" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Insider3">
<xs:complexType>
<xs:sequence>
<xs:element ref="Internal" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Internal-low">
<xs:complexType>
<xs:sequence>
<xs:element name="myString" type="xs:string" maxOccurs="unbounded"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Internal">
<xs:complexType>
<xs:sequence>
<xs:element name="Step" type="xs:string"></xs:element>
<xs:element ref="Internal-low" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
myXML.xml :
<?xml version="1.0" encoding="UTF-8"?>
<RootElem xmlns="http://www.example.com/myXSD"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com/myXSD myXSD.xsd">
<Insider1>
<Internal>
<Step>My step 1</Step>
<Internal-low>
<myString>My string 1 for step 1</myString>
</Internal-low>
</Internal>
<Internal>
<Step>My step 2</Step>
<Internal-low>
<myString>My string 1 for step 2</myString>
</Internal-low>
</Internal>
<Internal>
<Step>My step 3</Step>
<Internal-low>
<myString>My string 1 for step 3</myString>
<myString>My string 2 for step 3</myString>
</Internal-low>
</Internal>
</Insider1>
<Insider2>
<Internal>
<Step>My step 1</Step>
<Internal-low>
<myString>My string 1 for step 1</myString>
</Internal-low>
</Internal>
<Internal>
<Step>My step 2</Step>
<Internal-low>
<myString>My string 1 for step 2</myString>
</Internal-low>
</Internal>
<Internal>
<Step>My step 3</Step>
<Internal-low>
<myString>My string 1 for step 3</myString>
<myString>My string 2 for step 3</myString>
</Internal-low>
</Internal>
</Insider2>
<Insider3>
<Internal>
<Step>My step 1</Step>
<Internal-low>
<myString>My string 1 for step 1</myString>
</Internal-low>
</Internal>
<Internal>
<Step>My step 2</Step>
<Internal-low>
<myString>My string 1 for step 2</myString>
</Internal-low>
</Internal>
<Internal>
<Step>My step 3</Step>
<Internal-low>
<myString>My string 1 for step 3</myString>
<myString>My string 2 for step 3</myString>
</Internal-low>
</Internal>
</Insider3>
</RootElem>
Everything works fine here. The problem is with the InsiderX
elements. There are about 10 InsiderX
elements in my actual XSD which may be increasing over time. So I need to compress the XSD code so that adding or removing any InsiderX
element is simpler as doing so now requires adding/removing 7 lines of redundant code. And how can I make sure that one and only one of each of the InsiderX
element occurs in my XML.
Also I would like to know what are other options in a XSD to replace <xs:sequence>
. I don't want alternate to this, but want to know what are other possible options like <xs:choice>
.
You can shorten your XSD by creating a reusable type like this.
You've already covered this scenario with your original schema. Modify your XML document by duplicating the Insider1 node for example like this
and try to validate this against your schema. You'll get an error something like this: cvc-complex-type.2.4.a: Invalid content was found starting with element 'Insider1'. One of '{"http://www.example.com/myXSD":Insider2}' is expected.
Well I'm not sure how to answer this, because this question is really too broad, however take a look at the XML Schema specification for complex type definitions. It says that instead of a sequence you can use group, all or choice. I hope this will get you on the right track.