XSD: What's the difference between these two? - xsd

In the first one, I put the minOccurs and maxOccurs in the sequence element:
<xs:element name="Prerequisites" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="Prerequisite" type="PrerequisiteType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
In the second one, I put it in the contained element element:
<xs:element name="Prerequisites" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="Prerequisite" type="PrerequisiteType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>

In this particular case there is no difference, i.e. both definitions describe the same language.
What you define in first example is the limit of the occurrences of the whole sequence, in the second case only of one element of the sequence.

Related

xsd Schema validation; xs:choice and min/max-occurs

We have an xml file that consists of one root element, a directly following element and after that 0 to 255 other elements of one specific type.
Currently, our XSD file looks like this:
<xs:element name="TIM">
...
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="POINT" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:documentation xml:lang="en">
Point
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element ref="VALUE" minOccurs="0" maxOccurs="255">
<xs:annotation>
<xs:documentation xml:lang="en">
Value
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:choice>
...
</xs:element>
How would I have to change this to say "Element Point once at the top, afterwards only ElementValue"?
Sounds like you want a simple sequence xs:sequence i.e. <xs:sequence><xs:element ref="POINT">..</xs:element><xs:element ref="VALUE" minOccurs="0" maxOccurs="255">..</xs:element></xs:sequence>.

XSD: Divide scheme using a choice of sequences

A part of my xsd looks as follows:
<xs:element name="my_element" minOccurs="1 maxOccurs="unbounded">
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element name="sequence_1" type="xs:string"/>
<xs:element name="ID1" type="xs:string"/>
<xs:element name="TYPE1" type="xs:string"/>
</xs:sequence>
<xs:sequence>
<xs:element name="sequence_2" type="xs:string"/>
<xs:element name="ID2" type="xs:string"/>
<xs:element name="TYPE2" type="xs:string"/>
</xs:sequence>
</xs:choice>
</xs:complexType>
</xs:element>
The first element name of the sequence decides about th following nodes.
If I now have a lot of different sequences with some elements inside my xsd doesn't look very clear.
Is it possible to separate the sequences (like I can do it for complexType)?
You can use group :
<xs:group name="seqGroup_x">
<xs:sequence>
<xs:element name="sequence_x" type="xs:string"/>
<xs:element name="ID" type="xs:string"/>
...
</xs:sequence>
</xs:group>
<xs:complexType name="yourType">
<xs:group ref="seqGroup_x"/>
<xs:attribute name="anotherattr" type="xs:string"/>
</xs:complexType>

XSD: How to have (A*|B*), C?, (A*|B*)

I have a XSD with XML elements A, B, and C.
I would like these to appear in a parent element in this way:
A and B can appear any times, C only once, optionally.
The order does not matter, but A and B should ideally be "together",
(so it's rather (A*), C?, (B*) | (B*), C?, (A*)), but the "A and B together" is not necessary).
How can I achieve that with XSD?
Actual XSD what I have tried:
<!-- Hint -->
<xs:element name="hint">
<xs:complexType mixed="true">
<xs:sequence>
<xs:choice>
<xs:element ref="tag" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="link" minOccurs="0" maxOccurs="unbounded" />
</xs:choice>
<xs:sequence>
<xs:element name="message" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
<xs:choice>
<xs:element ref="tag" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="link" minOccurs="0" maxOccurs="unbounded"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
But that gives me
cos-nonambig: <ns>:link and <ns>:link (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles.
Basically, the need is to have any mix of A, B, C, where C appears
only once.
XSD 1.1 Solution
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
vc:minVersion="1.1">
<xs:complexType name="SolutionType">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="A"/>
<xs:element name="B"/>
<xs:element name="C"/>
</xs:choice>
<xs:assert test="count(c) <= 1"/>
</xs:complexType>
</xs:schema>
The above xs:assertion assumes that you mean "C appears at most once" but can easily be adjusted to require C to appear exactly once.
A and B can appear any times, C only once, optionally. The order does
not matter, but A and B should ideally be "together"
XSD 1.0 Solution
You'll have to impose an ordering to avoid violating Unique Particle Attribution:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="SolutionType">
<xs:sequence>
<xs:element name="A" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="C" minOccurs="0"/>
<xs:element name="B" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
At least this achieves your preference toward keeping A and B together.
The "Unique Particle Attribution" basically means that every element during validation needs to be deterministically assignable to certain XSD "branch". And that can be checked when validating the XSD.
I found out that the (only?) way to avoid abiguity is to list all combinations of A,B,C in a <xs:choice>, while setting minOccurs="1" as appropriate to break the ambiguity. That gives quite a few choices, but for 3 elements, still doable.
This is for the case where I leave 'C' in the beginning:
<xs:sequence>
<xs:element name="message" minOccurs="0" maxOccurs="1"/>
<xs:choice>
<xs:sequence>
<xs:element ref="link" minOccurs="1" maxOccurs="unbounded" />
<xs:element ref="tag" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:sequence>
<xs:element ref="tag" minOccurs="1" maxOccurs="unbounded"/>
<xs:element ref="link" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:sequence/>
</xs:choice>
</xs:sequence>
Not closing this question, I believe there's a better option even in XSD 1.0.

xsd: define an element that can be repeated an even number of times

with xsd, is there a way in which we can define an element that is repeated an even number of times? with my information it is not possible with the attributes minOcurs and maxOccurs.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xs:element name="A">
<xs:complexType>
<xs:sequence>
<xs:element name="B" maxOccurs="?" minOccurs="?"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
How about this:
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="B" maxOccurs="2" minOccurs="2"/>
</xs:sequence>

How do you make an XSD element required or not required depending on the context?

We have a definition of Person element where we want different elements to be required depending on
what they are doing. For example, if they are adding a Person, then different elements are required
to be sent versus updating a Person. Below in the example, the Person type is currently duplicated, which
of course is wrong. Is there a good way of representing this in the xsd so we can reuse the Person type.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Person">
<xs:annotation>
<xs:documentation>This is the definition when changing a person</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="PartyName" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="GenderCode" type="GenderCode_Type" minOccurs="0" maxOccurs="1"/>
<xs:element name="BirthDate" type="xs:date" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Person">
<xs:annotation>
<xs:documentation>This is the definition when adding a person</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="PartyName" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="GenderCode" type="GenderCode_Type" minOccurs="1" maxOccurs="1"/>
<xs:element name="BirthDate" type="xs:date" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
The simplest way to have two different types for Person elements is to use local declarations of Person in the two different contexts you have in mind. For example, you might say:
<xs:element name="Add">
<xs:complexType>
<xs:sequence>
<xs:element name="Person" type="AddPerson"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Update">
<xs:complexType>
<xs:sequence>
<xs:element name="Person" type="ChangePerson"/>
</xs:sequence>
</xs:complexType>
</xs:element>
This example assumes that you have redefined your two complex types as AddPerson and ChangePerson.
If additionally you want to have the two complex types be explicitly related, you can derive them both by restriction from a generic Person type.
<xs:complexType name="Person">
<xs:annotation>
<xs:documentation>This is the generic
definition for persons</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="PartyName" type="xs:string"
minOccurs="0" maxOccurs="1"/>
<xs:element name="GenderCode" type="GenderCode_Type"
minOccurs="0" maxOccurs="1"/>
<xs:element name="BirthDate" type="xs:date"
minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChangePerson">
<xs:annotation>
<xs:documentation>This is the definition
when changing a person</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:restriction base="Person">
<xs:sequence>
<xs:element name="PartyName" type="xs:string"
minOccurs="0" maxOccurs="1"/>
<xs:element name="GenderCode" type="GenderCode_Type"
minOccurs="0" maxOccurs="1"/>
<xs:element name="BirthDate" type="xs:date"
minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="AddPerson">
<xs:annotation>
<xs:documentation>This is the definition
when adding a person</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:restriction base="Person">
<xs:sequence>
<xs:element name="PartyName" type="xs:string"
minOccurs="1" maxOccurs="1"/>
<xs:element name="GenderCode" type="GenderCode_Type"
minOccurs="1" maxOccurs="1"/>
<xs:element name="BirthDate" type="xs:date"
minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
Here, the generic type Person is identical to the AddPerson type; I've defined AddPerson using a vacuous restriction just for the symmetry of deriving both of the operation-specific types from the generic type.
Whether having such an explicit relation among your types actually helps you achieve your goals will depend, of course, in part on what use your system makes of your schema type definitions.

Resources