I need to solve the following problem.
//pseudo algorithm
No, I don't think this is possible. Your requirements seem mutually exclusive. You can either have:
Elements in any order but not more than one (or zero) of each type
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:all>
<xs:element name="elm1" minOccurs="0" maxOccurs="1" />
<xs:element name="elm2" minOccurs="0" maxOccurs="1" />
<xs:element name="elm3" minOccurs="0" maxOccurs="1"/>
<xs:element name="elm4" minOccurs="0" maxOccurs="1"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>
<?xml version="1.0" ?>
<root>
<elm4 />
<elm1 />
<elm3 />
</root>
or
Elements in fixed order and each with specific number of occurrences
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="elm1" minOccurs="0" maxOccurs="2" />
<xs:element name="elm2" minOccurs="0" maxOccurs="1" />
<xs:element name="elm3" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="elm4" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<?xml version="1.0"?>
<root>
<elm1 />
<elm1 />
<elm2 />
<elm4 />
<elm4 />
<elm4 />
<elm4 />
</root>
If your n
values not too big and you're desperate you can make a content model that accounted for every possible combination, but that grows complex exponentially.
The best solution is to use a tool that supports XML Schema 1.1 (such as Xerces or Saxon), which relaxes restrictions on all
group occurrence values. From section G.1.3 of the spec:
Several of the constraints imposed by version 1.0 of this specification on all-groups have been relaxed:
a. Wildcards are now allowed in all groups.
b. The value of maxOccurs may now be greater than 1 on particles in an all group. The elements which match a particular particle need not be adjacent in the input.
c. all groups can now be extended by adding more members to them.
Failing that, the general XML Schema 1.0 solution is to specify a relaxed model in the schema (no limits on the element occurrences) and then enforce the constraints you care about in another layer, which might be custom code or XSLT, for instance.
You can allways use the minOccurs
and maxOccurs
attributes in a XSD-schema. This will allow you to set the number of elements which are allowed in a specific element. More info in this tutorial
An example of how this is used in a choice-block is represented here, like this:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="document">
<xs:complexType>
<xs:choice minOccurs="1" maxOccurs="unbounded">
<xs:element name="A" minOccurs="1" maxOccurs="1"/>
<xs:element name="B" minOccurs="0" maxOccurs="3" />
<xs:element name="C" minOccurs="0" maxOccurs="1"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
It's not possible in xml-schema. You can use a choice in combination with something like schematron:
<schema xmlns="http://purl.oclc.org/dsdl/schematron">
<pattern>
<title>Occurance rules</title>
<rule context="elm1">
<assert test="(count(//elm1) > 0) and (count(//elm1) < 3)">an error message</assert>
</rule>
</pattern>