Reputation: 165
I need to define a set of XSDs. Each XSD will have a header element, and that header is identical, except for some elements in the middle.
So, I would have:
xml1:
<req1>
<head>
<common1/>
<common2/>
<choice1/>
<choice2/>
<common3/>
</head>
<data1>...</data1>
</req1>
xml2:
<req2>
<head>
<common1/>
<common2/>
<choice2/>
<choice3/>
<common3/>
</head>
<data2>...</data2>
</req2>
where choice1, choice2, choice3 is in a <choice>
set, like
<choice>
<choice2/>
<choice3/>
</choice>
and can have different choices and numbers of elements between the different request types.
I would really like to be able to define this in a single XSD for the header, and then include that in req1.xsd and req2.xsd. I can't figure out how to swap this <choice>
out dynamically. If I didn't have the <common3/>
part, I could use a base element, but my understanding is that when I add anything to a base, it only adds at the end. Any way I can replace in the middle, or add in the middle when using a base?
Upvotes: 2
Views: 1574
Reputation: 21658
One way to do it is by using substitution groups. You define a base XSD, for your boilerplate.
Base.xsd
<?xml version="1.0" encoding="utf-8"?>
<!--W3C Schema generated by QTAssistant/XML Schema Refactoring Module (http://www.paschidev.com)-->
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="head">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="common1" type="xsd:anyType"/>
<xsd:element name="common2" type="xsd:anyType"/>
<xsd:element ref="headerPlaceholder"/>
<xsd:element name="common3" type="xsd:anyType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="headerPlaceholder" type="headerPlaceholder" abstract="true"/>
<xsd:complexType name="headerPlaceholder" abstract="true"/>
<xsd:complexType name="request" abstract="true">
<xsd:sequence>
<xsd:element ref="head"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Then you can build your req1 and req independently.
Req1.xsd
<?xml version="1.0" encoding="utf-8"?>
<!--W3C Schema generated by QTAssistant/XML Schema Refactoring Module (http://www.paschidev.com)-->
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:include schemaLocation="SubstitutionGroupHeader.xsd"/>
<xsd:element name="req1" type="req1"/>
<xsd:complexType name="req1">
<xsd:complexContent>
<xsd:extension base="request">
<xsd:sequence>
<xsd:element name="data1"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="choice1" substitutionGroup="headerPlaceholder">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="headerPlaceholder"/>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="choice2" substitutionGroup="headerPlaceholder">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="headerPlaceholder"/>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
The structure looks like this:
Req2.xsd
<?xml version="1.0" encoding="utf-8"?>
<!--W3C Schema generated by QTAssistant/XML Schema Refactoring Module (http://www.paschidev.com)-->
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:include schemaLocation="SubstitutionGroupHeader.xsd"/>
<xsd:element name="req2" type="req2"/>
<xsd:complexType name="req2">
<xsd:complexContent>
<xsd:extension base="request">
<xsd:sequence>
<xsd:element name="data2"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="choice3" substitutionGroup="headerPlaceholder">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="headerPlaceholder"/>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="choice4" substitutionGroup="headerPlaceholder">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="headerPlaceholder"/>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:schema>
The structure for req2:
I put choice1/2 and choice3/4 in req1 and req2 just to have no overlap between content. So the file structure looks something like this:
The overall relationship between XSD components:
If you want to have the same choice2 referenced from both req1 and req2, you would have to refactor choice2 in its own file, etc.
A lot could be discussed about choices vs substitution groups, but that's another thing...
Upvotes: 3