Tag: choice

xsd schema – repeating elements via unbouned choice and sequence

For the schema below with choice:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.bawi.com/schema" targetNamespace="http://www.bawi.com/schema" elementFormDefault="qualified">
    <xs:element name="MyRootElement">
        <xs:complexType>

	    <!-- allow either (zero or more of A) or (only exactly single B) -->	
            <xs:choice>
                <xs:element name="A" maxOccurs="unbounded"/>
                <xs:element name="B" />
            </xs:choice>
        </xs:complexType>
    </xs:element>
</xs:schema>

Screen Shot 2017-08-07 at 13.33.10

we get valid xmls:
– no children

<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
</MyRootElement>

– zero or more A element(s)

<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
  <A></A>
  <A/>
</MyRootElement>

– exactly one B element

<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
  <B/>
</MyRootElement>

However, combination of A and B is not possible:

<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
  <A></A>
  <B/>
</MyRootElement>

as we get

Invalid content was found starting with element 'B'. One of '{"http://www.bawi.com/schema":A}' is expected.

and also not valid xml:

<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
  <B/>
  <A></A>
</MyRootElement>

due to

Invalid content was found starting with element 'A'. No child element is expected at this point.

In order to get xml with many A elements and single B we would define a sequence:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.bawi.com/schema" targetNamespace="http://www.bawi.com/schema" elementFormDefault="qualified">
    <xs:element name="MyRootElement">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="A" minOccurs="0" maxOccurs="unbounded"/>
                <xs:element name="B" />
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Screen Shot 2017-08-07 at 13.47.48

so that the xml below is valid:

<MyRootElement xmlns="http://www.bawi.com/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bawi.com/schema schema.xsd">
  <A></A>
  <B/>
</MyRootElement>

For validation I have used the following code:

import org.xml.sax.SAXException;

import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.File;
import java.io.IOException;

public class MyValidator {
    public static void main(String[] args) throws SAXException, IOException {
        File schemaFile = new File("schema.xsd");
        Source xmlFile = new StreamSource("generated.xml");
        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = schemaFactory.newSchema(schemaFile);
        Validator validator = schema.newValidator();
        validator.validate(xmlFile);
        System.out.println(xmlFile.getSystemId() + " is valid");
    }
}
Advertisements