XSD "one or both" choice construct leads to ambiguous content model - xsd

I am trying to make a simple XSD choice construct allowing either one or both of two referenced elements, but not none. The construct is similar to below but I keep getting an ambiguity error. What am I missing?
<xs:schema xmlns:xs="...">
<xs:element name="Number" type="xs:integer"/>
<xs:element name="Text" type="xs:string"/>
<xs:element name="RootStructure">
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:sequence>
<xs:element ref="Number"/>
<xs:element ref="Text"/>
</xs:sequence>
<xs:element ref="Number"/>
<xs:element ref="Text"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

The usual way to do it is this:
<xs:schema xmlns:xs="...">
<xs:element name="Number" type="xs:integer"/>
<xs:element name="Text" type="xs:string"/>
<xs:element name="RootStructure">
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:sequence>
<xs:element ref="Number"/>
<xs:element ref="Text" minOccurs="0"/>
</xs:sequence>
<xs:element ref="Text"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Some additional hint, if you have multiple elements linked and you want one bundle of elements or the other bundle, or both, you can do it like this:
<xsd:complexType name="ComplexTypeName">
<xsd:choice>
<xsd:sequence>
<xsd:element name="theElement" />
<xsd:element name="theElementIsFlagged" />
<xsd:choice>
<xsd:sequence>
<!-- note the empty sequence block -->
</xsd:sequence>
<xsd:sequence>
<xsd:element name="theOtherElement" />
<xsd:element name="theOtherElementIsFlagged" />
</xsd:sequence>
</xsd:choice>
</xsd:sequence>
<xsd:sequence>
<xsd:element name="theOtherElement" />
<xsd:element name="theOtherElementIsFlagged" />
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
Just in case some of you bump into the same issue!!

Related

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 choice for multiple elements

I would like my Xml file to look like the following
<root>
<name>a</name>
<age>23</age>
</root>
or
<root>
<empno>b<empno>
<designation>ase</designation>
</root>
is it possible to create a XML schema for the above using a "choice" indicator?something like below.
<xsd:element name="root">
<xsd:complexType>
<xsd:choice>
<xsd:element name="name"/>
<xsd:element name="age" />
or
<xsd:element name="empno"/>
<xsd:element name="designation" />
<xsd:choice>
</xsd:complexType>
<xsd:element>
Is it possible to do like this?
Yes, You are almost there.. just missing a sequence .. Since it's the set of fields you have to wrap them under sequence..
These sequence tags will be under <Choice> tag. Now either of these set of tags (Sequence) will be validated.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root" type="root"/>
<xs:complexType name="root">
<xs:choice>
<xs:sequence>
<xs:element name="empno" type="xs:string" />
<xs:element name="designation" type="xs:string" />
</xs:sequence>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="age" type="xs:unsignedByte" />
</xs:sequence>
</xs:choice>
</xs:complexType>
</xs:schema>
-----------------------------------------------------------------------------------------
I would like to add one more suggestion here:
I observe that you use nested declarations .. like this:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="trunk">
<xs:complexType>
<xs:sequence>
<xs:element name="branch1" type="xs:string"/>
<xs:element name="branch2" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="other" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Always prefer usage of Custom types! Like this:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root" type="root"/>
<xs:complexType name="root">
<xs:sequence>
<xs:element name="trunk" type="trunk"/>
<xs:element name="other" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="trunk">
<xs:sequence>
<xs:element name="branch1" type="xs:string"/>
<xs:element name="branch2" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
This improves readability and you can reuse the complexType/simpleType ..
hope it helps..

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.

XS:any schemavalidation

I am getting validation error in the below xsd .
cos-nonambig: "http://alert.schemas.tr.com/TriggerSynchronizationService/Data/2010-02-08/":resyncRequestID and WC[##any] (or elements from their substitution group) violate
"Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles.
I think i did not declare xs:any properly.
<xs:complexType name="GenerationTriggerData">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="resyncRequestID" type="xs:int" />
<xs:element minOccurs="0" maxOccurs="1" name="userID" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="alertID" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="triggerID" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="logicalType" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="version" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="state" type="q1:State_Enum" />
<xs:element minOccurs="0" maxOccurs="1" name="criteria" xmlns:q2="http://expressions.schemas.tfn.thomson.com/2006-09-04/" type="q2:ExpressionRoot" />
<xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
</xs:sequence>
</xs:complexType>
XSD doesn't allow for ambiguous content. UPA is about the parser being able to figure out where it is relative to the XSD, unambiguously; even look-ahead is not allowed.
Since your xsd:any can be (##)any namespace, then resyncRequestID would match it; in that case, is that the first (optional) one, or the wildcard? Here the content is clearly ambigous and no look-ahead would help.
One way is to have xsd:any definition changed such that it won't match any of the content preceding it. Constraining the namespace is always an easy way to do it.
Alternatively, make the particle right before xsd:any mandatory. This way the reader would know where "the wild" begins...
If that is not an option, introduce a special "marker" tag right before xs:any; it must be mandatory!
The above are typically called "refactoring an XSD" to satisfy XSD's UPA design constraint.

XSD: disallow empty element

I have an XML Schema that looks like this:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="A" minOccurs="0" maxOccurs="1"/>
<xs:element name="B" minOccurs="0" maxOccurs="1"/>
<xs:element name="C" minOccurs="0" maxOccurs="32"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
The following is valid according to this schema:
<root xsi:noNamespaceSchemaLocation="MySchema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
</root>
However, I'd like to make the above XML invalid.
More specifically, I'd like to require:
1. that the <root> have at least one child element, be it an <A>, a <B>, or a <C>, and
2. that the <root> have at most one <A> child, and at most one <B> child.
Suggestions?
Solution is:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:choice>
<xs:sequence>
<xs:element name="A"/>
<xs:element name="B" minOccurs="0"/>
<xs:element name="C" minOccurs="0" maxOccurs="32"/>
</xs:sequence>
<xs:sequence>
<xs:element name="B"/>
<xs:element name="C" minOccurs="0" maxOccurs="32"/>
</xs:sequence>
<xs:sequence>
<xs:element name="C" minOccurs="1" maxOccurs="32"/>
</xs:sequence>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
How about using exactly one xs:choice of A, B, or C followed by 0 or more of each of them?
Ah, with your edit it would have to be something like a choice of A, AB, or B followed by 0 to 32 Cs. Yes?
Have you tried adding minOccurrs=1 to the xs:sequence?

Resources