Conditional required elements in an XSD
This is possible in XSD 1.1; below is a simplified example, which assumes MainApplicant and WhereSigned are mandatory when CustomerId is equal to zero.
<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xtm="http://paschidev.com/schemas/metadata/xtm">
<xsd:complexType name="Request">
<xsd:all>
<xsd:element name="UserID" type="xsd:string" />
<xsd:element name="Password" type="xsd:string" />
<xsd:element name="ReferenceNumber" type="xsd:string" minOccurs="0"/>
<xsd:element name="CustomerId" type="xsd:integer"/>
<xsd:element ref="WhereSigned" minOccurs="0"/>
<xsd:element name="ContactName" type="xsd:string" minOccurs="0" />
<xsd:element name="ContactTelephone" type="xsd:string" minOccurs="0" />
<xsd:element name="ContactFax" type="xsd:string" minOccurs="0" />
<xsd:element name="ContactEmail" type="xsd:string" minOccurs="0" />
<xsd:element ref="MainApplicant" minOccurs="0" />
<xsd:element ref="JointApplicant" minOccurs="0" />
<xsd:element ref="Asset" minOccurs="0" />
</xsd:all>
<xsd:assert test="CustomerId[. eq 0] and WhereSigned and MainApplicant or CustomerId[. ne 0]" />
</xsd:complexType>
<xsd:element name="Asset"/>
<xsd:element name="MainApplicant" />
<xsd:element name="JointApplicant" />
<xsd:element name="WhereSigned" />
</xsd:schema>
Minimum valid XML, when CustomerId is zero:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Request">
<UserID>UserID1</UserID>
<Password>asodasqZX==</Password>
<CustomerId>0</CustomerId>
<WhereSigned/>
<MainApplicant/>
</root>
When CustomerId is non-zero, then this is the minimum XML:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Request">
<UserID>UserID1</UserID>
<Password>asodasqZX==</Password>
<CustomerId>1</CustomerId>
</root>
The conditional can be easily controlled (see the @test expression); add regular XSD constraints as needed (e.g. if your CustomerId needs to be greater than or equal to zero, then make it nonNegativeInteger, etc.)
Related videos on Youtube
Shawson
I'm a web and mobile developer- current in employment as a Senior Developer at LinnWorks.linkedin
Updated on October 19, 2022Comments
-
Shawson over 1 year
I have a requirement for an xml schema which accepts either a request with the customer or with the customer id. If the customer Id is 0 then we need the customer data, if it's > 0 then customer data is optional (They can submit ammendements). My XSD looks like this at the moment;
<xs:complexType> <xs:any> <xs:element name="UserID" type="xs:string" minOccurs="1"/> <xs:element name="Password" type="xs:string" minOccurs="1"/> <xs:element name="ReferenceNumber" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="CustomerId" minOccurs="1" maxOccurs="1" type="xs:integer"/> <xs:element ref="WhereSigned"/> <xs:element name="ContactName" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="ContactTelephone" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="ContactFax" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="ContactEmail" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element ref="MainApplicant" maxOccurs="1"/> <xs:element ref="JointApplicant" minOccurs="0" maxOccurs="1"/> <xs:element ref="Asset" minOccurs="0" maxOccurs="1"/> </xs:any> </xs:complexType>
I need something a bit like this... (I wish it were this simple but alas not..)
<xs:complexType> <xs:choice> <xs:any> <xs:element name="UserID" type="xs:string" minOccurs="1"/> <xs:element name="Password" type="xs:string" minOccurs="1"/> <xs:element name="ReferenceNumber" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="CustomerId" minOccurs="1" maxOccurs="1"> <xs:simpleType> <xs:restriction base="xs:integer"> <xs:minInclusive value="0"/> <xs:maxInclusive value="0"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element ref="WhereSigned"/> <xs:element name="ContactName" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="ContactTelephone" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="ContactFax" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="ContactEmail" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element ref="MainApplicant" maxOccurs="1"/> <xs:element ref="JointApplicant" minOccurs="0" maxOccurs="1"/> <xs:element ref="Asset" minOccurs="0" maxOccurs="1"/> </xs:any> <xs:any> <xs:element name="UserID" type="xs:string" minOccurs="1"/> <xs:element name="Password" type="xs:string" minOccurs="1"/> <xs:element name="ReferenceNumber" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="CustomerId" minOccurs="1" maxOccurs="1"> <xs:simpleType> <xs:restriction base="xs:integer"> <xs:minInclusive value="1"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element ref="Asset" minOccurs="0" maxOccurs="1"/> </xs:any> </xs:choice> </xs:complexType>
Any XSD experts (do these even exist?!) who are able to lend a hand or some advice?
-
potame over 8 yearsAre you allowed to use schema version 1.1? In this case, you can assertions -
xs:assert
(w3.org/TR/xmlschema11-1/#cAssertions)
-
-
Shawson over 8 yearsThis is EXACTLY what I was looking for, thank you! Minor complication is that .net apparently does not yet support xsd1.1 believe it or not!