XS:any schemavalidation - xsd

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.

Related

Using x:anyType instead of xsi:type gives Jaxb marshalling errors

I want to avoid xsi:type in an element and add the child elements at runtime based on some condition
I have option element defined as follows of type xs:anyType
<xs:complexType name="prod">
<xs:sequence>
<xs:element type="xs:anyType" name="option" minOccurs="0" maxOccurs="1"</xs:element>
</xs:sequence>
</xs:complexType>
used in element mapping as follows
<xs:element name="mappings">
<xs:complexType>
<xs:sequence>
<xs:element type="prod" name="productionSystem" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
I have need to add following option type as one of the following
<xs:complexType name="Text">
<xs:sequence>
<xs:element type="xs:short" name="id" />
<xs:element type="xs:string" name="name" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Value">
<xs:sequence>
<xs:element type="xs:short" name="id" />
<xs:element type="xs:string" name="name" />
<xs:element name="psValue" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="value" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
so basically one element option can be either of type Text or Value.
I want to avoid xsi:type in the xml. hence defined as xs:anyType. However at runt time Jaxb Marshalling fails with error
"any of its super class is known to this context". How to ensure Text and Value are in Jaxb Context.
Can someone pls guide on same.
Thanks,
Anjana

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.

Question about xsd. Elements inside complex type must be allowed in any order

If you look at the following xsd fragment you can conclude that the corresponding xml will first contain cars followed by busses eg:
car,car,bus,bus
HOWEVER I want the xml to be able to contain
car,bus,car,bus
What change do I need to make in the xsd below in order to achieve this?
<xs:element name="body">
<xs:complexType>
<xs:sequence>
<xs:element name="session" type="tns:session" />
<xs:element minOccurs="0" maxOccurs="unbounded" name="car" type="tns:car" />
<xs:element minOccurs="0" maxOccurs="unbounded" name="bus" type="tns:bus" />
</xs:sequence>
</xs:complexType>
</xs:element>
It's a bit cumbersome, but you might achieve what you're looking for like this:
create a <xs:choice> element with your car and bus elements inside; this defines that one of the contained elements can be used
make sure to have the attribtues minOccurs=1 and maxOccurs=unbounded on that <xs:choice> - this gives you any number of either car or bus elements - any number, any combination
So your XML schema would look something like this (I added some stuff just to be able to generate a sample XML and verify it works - tweak as needed):
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="body">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element minOccurs="0" maxOccurs="unbounded" name="car" type="CarType" />
<xs:element minOccurs="0" maxOccurs="unbounded" name="bus" type="BusType" />
</xs:choice>
</xs:complexType>
</xs:element>
<xs:complexType name="CarType">
<xs:sequence>
<xs:element name="Maker" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="BusType">
<xs:sequence>
<xs:element name="Maker" type="xs:string" />
<xs:element name="Capacity" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:schema>
use <xs:any> insted of <xs:sequence>

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

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!!

Xsd recursion of complexTypes

I am just learning XML/XSD and am struggling with the implementation of an XML-schema which models a folder structure.
What I had in mind was defining a complexType for the folder which can have additional folder instances that represent subfolders. Using the xsd schema validator here always returns that the schema is invalid.
I tried defining the complexType up front and then using the ref keyword for subfolders:
<xs:complexType name="tFolder">
<xs:sequence>
<xs:element name="Path" type="tFolderType" msdata:Ordinal="0" />
<xs:element ref="Folder" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="File" nillable="true" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent msdata:ColumnName="File_Text" msdata:Ordinal="0">
<xs:extension base="xs:string">
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Type" type="tFolderType" />
As for the element itself:
<xs:element name="Folder" type="tFolder" />
The error returned by the validator is:
"Cannot resolve the name 'Folder' to a(n) 'element declaration' component."
and the error occurs at the line
<xs:element ref="Folder" minOccurs="0" maxOccurs="unbounded" />
Defining the complexType within the element itself yields the exact same error:
<xs:element name="Folder">
<xs:complexType>
<xs:sequence>
<xs:element name="Path" type="tFolderType" msdata:Ordinal="0" />
<xs:element ref="Folder" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="File" nillable="true" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:simpleContent msdata:ColumnName="File_Text" msdata:Ordinal="0">
<xs:extension base="xs:string">
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Type" type="tFolderType" />
</xs:complexType>
</xs:element>
What I've read, this kind of recursion should work using ref.
Can anyone tell me what I've done wrong? Maybe the xsd validator is just faulty? If so, does anyone know a better alternative? I've tried using the one from w3.org as well, but it seems to be taken offline...
I think this is the way to do it (don't use ref):
<element name="test" type="tns:TestType"></element>
<complexType name="TestType">
<sequence>
<element name="test" type="tns:TestType"></element>
</sequence>
</complexType>

Resources