XSD: indicate that the selection must have at least one from the list, but not more than one

It made me angry for hours. I read all the relevant XSD questions about SO and the rest of the Internet, and still the answer eludes me.

I need an XML schema that requires at least one of the list items, but each item can only be displayed 0 or 1 time.

This is similar to this question: An XML schema construct for "any one or more of these elements, but must be at least one"

but I was not able to limit the upper limit: I apparently misused maxOccurs .

Here, where I settled on my scheme:

 <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:complexType name="Selects"> <xs:sequence minOccurs="2" maxOccurs="4"> <xs:choice> <xs:element name="aaa" minOccurs="1" maxOccurs="1"/> <xs:element name="bbb" minOccurs="1" maxOccurs="1"/> <xs:element name="ccc" minOccurs="1" maxOccurs="1"/> <xs:element name="ddd" minOccurs="1" maxOccurs="1"/> </xs:choice> </xs:sequence> </xs:complexType> <xs:element name="baseElement"> <xs:complexType> <xs:sequence> <xs:element name="MyChoice" type="Selects"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> 

I tried minOccurs and maxOccurs by choice and element with no luck. Here is the XML that validates, although I do not want it:

 <?xml version="1.0" encoding="UTF-8"?> <baseElement xsi:noNamespaceSchemaLocation="myTest.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <MyChoice> <ddd/> <ddd/> </MyChoice> </baseElement> 

Here is an example of what I would like, if possible:

 <?xml version="1.0" encoding="UTF-8"?> <baseElement xsi:noNamespaceSchemaLocation="myTest.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <MyChoice> <ddd/> <aaa/> <ccc/> </MyChoice> </baseElement> 

I would like him to complain about a few ddd elements, but let anyone or everyone else in any order. I get an error if I have only one item in MyChoice, so at least something works.

What am I doing wrong? How to prevent checking multiple elements of the same element?

UPDATE

This was my solution (from the comments below):

Actually, xs: everyone did the trick. I changed the selection for everyone and added minOccurs = "0" maxOccurs = "1" to each element. With xs: all, minOccurs should be either 0 or 1, and maxOccurs should be 1. Thanks for your help - I'm ready to go now!

+4
source share
1 answer

Just move <xs:sequence minOccurs="2" maxOccurs="4"> around the selection to the point where you want to use it further. (you can also remove min / max meets = 1, since this is xs: the choice does)

 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:complexType name="Selects"> <xs:choice> <xs:element name="aaa" /> <xs:element name="bbb" /> <xs:element name="ccc" /> <xs:element name="ddd" /> </xs:choice> </xs:complexType> <xs:element name="baseElement"> <xs:complexType> <xs:sequence minOccurs="2" maxOccurs="4"> <xs:element name="MyChoice" type="Selects" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> 

This confirms the following:

 <baseElement xsi:noNamespaceSchemaLocation="myTest.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <MyChoice> <bbb></bbb> </MyChoice> <MyChoice> <ccc></ccc> </MyChoice> </baseElement> 

UPDATE

I think you have reached the limit of what you can achieve with XSD. I see no way to do this except by defining a “version” of type MyChoice for each possible combination (which will require different names MyChoice1, MyChoice2, etc.)

You can also use xs: all

  <xs:complexType name="Selects"> <xs:all minOccurs=2 maxOccurs=4> <xs:element name="aaa" /> <xs:element name="bbb" /> <xs:element name="ccc" /> <xs:element name="ddd" /> </xs:all> </xs:complexType> 

but that doesn’t stop you from having four <ddd/>

+3
source

Source: https://habr.com/ru/post/1382451/


All Articles