XSD validation error - choice is invalid, misplaced, or occurs too often [duplicate] - xsd

This question already has answers here:
Where does xsd:attribute declaration go? (A problem was found starting at: attribute.)
(1 answer)
How to make type depend on attribute value using Conditional Type Assignment
(1 answer)
Value of XML element depends on values of other elements in XSD?
(1 answer)
Closed 17 days ago.
I have a problem with validation of the case that if attribute "brand" has value "x" then it is required to use attribute "model" otherwise attribute "model" should not be used.
XSD part which I am using for that is as below :
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name = "deviceList" type="deviceType"/>
<xs:complexType name="deviceType">
<xs:attribute name="brand" type="xs:string"/>
<xs:attribute name="model" type="xs:string" use="prohibited"/>
<xs:choice>
<xs:sequence>
<xs:attribute name="A" use="required" fixed="1"/>
<xs:attribute name="B" use="required"/>
</xs:sequence>
<xs:attribute name="A" use="required"/>
</xs:choice>
</xs:complexType>
</xs:schema>
When validating the result is :
The content of 'variableType' is invalid. Element 'choice' is invalid, misplaced, or occurs too often.
To be fair I don't know why it is not validating properly ...
XML part which I am trying to validate:
<?xml version="1.1"?>
<!-- <deviceMappingFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="XSD file.xsd"> -->
<deviceList brand="x" model="yyy( model required if brand=x , if other not in use))"/>

Related

How to declare an xs:element with two different sets of attributes?

My new XML private language includes elements <figure>, representing illustrations (image + caption).
Whenever illustrations refer to some image in the local database I just want to type
<figure id="9809" width="full" />
to identify image number 9809 and its associated caption.
On the other side, if images come from outside I will need a slightly different syntax:
<figure href="https://some-url-here" width="full">Some ad hoc catpion</figure>
So far I have declared an element that combine both behaviours, like this:
<!-- Figures -->
<xs:simpleType name="FigureWidthEnum">
<xs:restriction base="xs:token">
<xs:enumeration value="center" />
<xs:enumeration value="half" />
<xs:enumeration value="full" />
</xs:restriction>
</xs:simpleType>
<xs:element name="figure">
<xs:complexType mixed="true">
<xs:complexContent>
<xs:extension base="Inline">
<xs:attribute name="href" type="URI" />
<xs:attribute name="id" type="xs:nonNegativeInteger" />
<xs:attribute name="width" type="FigureWidthEnum" default="full" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
It works fine but a fresh editor can mess with the 3 attributes and type impossible things I don't want to pass the Schema Validator that easy. For example:
<figure id="9809" width="full" href="https://some-unexpected-url">Some unexpected caption that should not be here</figure>
I want to have two completely separate sintaxes for <figure>, as if I could declare these two elements with the same name:
<xs:element name="figure">
<xs:complexType mixed="true">
<xs:complexContent>
<xs:extension base="Inline">
<xs:attribute name="href" type="URI" />
<xs:attribute name="width" type="FigureWidthEnum" default="full" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="figure">
<xs:complexType>
<xs:attribute name="id" type="xs:nonNegativeInteger" />
<xs:attribute name="width" type="FigureWidthEnum" default="full" />
</xs:complexType>
</xs:element>
In fact it is not possible.
Can it be done somehow?
Yes, it is possible with XSD 1.1, which provides <xs:alternative> element intended specifically for such requirements. Here's a complete XML schema I've designed to validate exactly as you need:
<?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">
<!-- Figures -->
<xs:simpleType name="FigureWidthEnum">
<xs:restriction base="xs:token">
<xs:enumeration value="center" />
<xs:enumeration value="half" />
<xs:enumeration value="full" />
</xs:restriction>
</xs:simpleType>
<!-- stub definition -->
<xs:complexType name="Inline"/>
<!-- 'figure' element is declared once, but its type has two alternatives -->
<xs:element name="figure">
<!-- The first alternative is selected, when the condition specified
in 'test' attribute is true. The condition must be a boolean XPath
expression. The '#id' returns the value of 'id' attribute. However,
when converted to boolean, it indicates whether 'id' attribute is
specified at all. The anonymous complexType inside <xs:alternative>
provides the element type valid for this case.
-->
<xs:alternative test="#id">
<xs:complexType>
<xs:attribute name="id" type="xs:nonNegativeInteger" />
<xs:attribute name="width" type="FigureWidthEnum" default="full" />
</xs:complexType>
</xs:alternative>
<!-- The second alternative has no 'test' attribute. That means, it must
be selected by default, when all other alternatives (with a specified
test condition) do not pass. Here, the anonymous complexType inside
<xs:alternative> defines the element type in case of reference:
when 'href' is present.
-->
<xs:alternative>
<xs:complexType mixed="true">
<xs:complexContent>
<xs:extension base="Inline">
<xs:attribute name="href" type="xs:anyURI" />
<xs:attribute name="width" type="FigureWidthEnum" default="full" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:alternative>
</xs:element>
<!-- this element is defined just to test the whole schema in XML below -->
<xs:element name="figures">
<xs:complexType>
<xs:sequence>
<xs:element ref="figure" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
A complete XML file this schema validates:
<?xml version="1.0" encoding="UTF-8"?>
<figures>
<!-- passes validation -->
<figure id="9809" width="full" />
<!-- passes validation -->
<figure width="full" href="https://some-unexpected-url">Some ad hoc caption</figure>
<!-- does not pass the validation -->
<figure id="9809" width="full" href="https://some-unexpected-url">
Some unexpected caption that should not be here
</figure>
</figures>
The validation was done with Apache Xerces 2.11.0 (XSD 1.1 aware).
Promo add-on. These links may be interesting for those working with XML schemas and WSDL: FlexDoc/XML XSDDoc & WSDLDoc – High-performance universal XML Schema / WSDL Documentation Generators with Diagrams

Using keyRef in XSD : How to refer a key located in a different XSD (out of scope error)

My system parses two XML files (via JAXB unmarshalling and xjc generated code)
componentModel.xml : generated from a modeling tool
detailedDesign.xml : manual, to add informations
In order to avoid to code checks upon content and structures, each file is validated with its own XSD
componentModel.xsd
detailedDesign.xsd
Both of these xsd inclulde "utilities.xsd" where common complex and simple types are defined
All works well
I now want to add consistency check :
unicity of Ids (names of components)
components in "detailsDesign" must refers one of the components in "componentModel" via the "name" and "nameRef" attributes
Here are the structures (i've simlplified names and structures in files to show only relevant informations)
Note : as you can see, i don't use any namespace except the default one
componentModel.xml
<?xml version="1.0" encoding="UTF-8"?>
<componentModel>
<components>
<component name="id1"> ... </component>
<component name="id1"> ... </component>
<component name="id2"> ... </component>
</components>
</componentModel>
componentModel.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xs:include schemaLocation="utilities.xsd" />
<xs:complexType name="CMComponent">
<xs:complexContent>
...
<xs:attribute name="name" type="MUUpperFirstName" use="required" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="CMComponents">
<xs:sequence>
<xs:element name="component" type="CMComponent" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="CMComponentModel">
<xs:complexContent>
<xs:sequence>
<xs:element name="components" type="CMComponents">
<!-- Key used to check "name" unicity and as a ref by nameRef attribute in detailedDesign model -->
<xs:key name="componentNameKey">
<xs:selector xpath="component" />
<xs:field xpath="#name" />
</xs:key>
</xs:element>
<xs:element name="functionalChains" minOccurs="0" maxOccurs="1" />
</xs:sequence>
<xs:attribute name="name" type="MUModelName" use="required" />
</xs:complexContent>
</xs:complexType>
<xs:element name="componentModel" type="CMComponentModel" />
</xs:schema>
utilities.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="MUString">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="MUUpperFirstName">
<xs:restriction base="MUString">
<xs:pattern value="([A-Z]+[a-zA-Z0-9]*[.])*[A-Z]+[a-zA-Z0-9]*"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="MUReferenceName">
<xs:restriction base="MUString">
<xs:pattern value="([A-Z]+[a-zA-Z0-9]*[.])*[a-zA-Z]+[a-zA-Z0-9]*"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
detailedDesign.xml
<?xml version="1.0" encoding="UTF-8"?>
<detailedDesignModel>
<components>
<component nameRef="id1"> ... </component>
<component nameRef="id2"> ... </component>
<component nameRef="id3"> ... </component>
</components>
</detailedDesignModel>
detailedDesign.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="utilities.xsd" />
<xs:include schemaLocation="componentModel.xsd" />
<xs:complexType name="DDMComponent">
<xs:complexContent>
...
<xs:attribute name="nameRef" type="MUReferenceName" use="required" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="DDMComponents">
<xs:sequence>
<xs:element name="component" type="DDMComponent" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="DDMDetailDesignModel">
<xs:complexContent>
<xs:sequence>
<xs:element name="components" type="DDMComponents">
<xs:keyref name="componentNameKeyRef" refer="componentNameKey">
<xs:selector xpath="component" />
<xs:field xpath="#nameRef" />
</xs:keyref>
</xs:element>
</xs:sequence>
</xs:complexContent>
</xs:complexType>
<xs:element name="detailDesignModel" type="DDMDetailDesignModel" />
</xs:schema>
It works for unicity of 'name' attribute among components (error retrieved from ValidationEventHandler set on unmarshaller) :
Duplicate key value [id1] declared for identity constraint of element "components".
But i can't get the "keyref" functionnality working (error retrieved from ValidationEventHandler set on unmarshaller) :
Identity Constraint error: identity constraint "KeyRef#272ed83b" has a keyref which refers to a key or unique that is out of scope.
How can i make the keyRef to see the Key defined in the orther XSD file
Thanks
Matth

How to constrain set of attributes in xsd

All
Please suggest me how to restrict in xsd schema the following:
<root>
<node action="action1" parameter="1" />
</root>
I need to require attribute "parameter" only if attribute "action" is defined.
Thanks,
W3C Schema doesn't have the ability to express conditionally required attributes.
Schematron is a great tool for validating that documents adhere to custom validation scenarios in which content is conditionally required.
You could define those attributes as optional in your schema, and then use Schematron to validate it against those conditional rules.
I created this xsd to attempt to solve the problem.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="XMLSchema1"
targetNamespace="http://tempuri.org/XMLSchema1.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/XMLSchema1.xsd"
xmlns:mstns="http://tempuri.org/XMLSchema1.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:group name="populated">
<xs:sequence >
<xs:element name="node">
<xs:complexType>
<xs:attributeGroup ref="actionattrib" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:group>
<xs:group name="unpopulated">
<xs:sequence >
<xs:element name="node">
<xs:complexType>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:group>
<xs:attributeGroup name ="actionattrib">
<xs:attribute name="action1" type="xs:string" />
<xs:attribute name="parameter" type="xs:int" />
</xs:attributeGroup>
<xs:element name="root">
<xs:complexType>
<xs:choice minOccurs ="0">
<xs:group ref="populated" />
<xs:group ref ="unpopulated" />
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
And a test method:
public static void Go()
{
string nameSpace = "http://tempuri.org/XMLSchema1.xsd";
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(nameSpace, "XMLSchema1.xsd");
XDocument myDoc1 = new XDocument(
new XElement(XName.Get("root", nameSpace),
new XElement( XName.Get("node", nameSpace ))
)
);
myDoc1.Validate(schemas, (o, e) => { Console.WriteLine(e.Message); });
}
And finally got this exception when validating:
Multiple definition of element 'http://tempuri.org/XMLSchema1.xsd:node' causes the content model to become ambiguous. A content model must be formed such that during validation of an element information item sequence, the particle contained directly, indirectly or implicitly therein with which to attempt to validate each item in the sequence in turn can be uniquely determined without examining the content or attributes of that item, and without any information about the items in the remainder of the sequence.
Which matches Mads result. His answer should be accepted.

JAXB generating wrong Namespace

I have a xsd (lets name it as afb) which imports another xsd (lets name it as kts). And I refer to an element of kts.xsd in afb.xsd along with correct namespaces.
But when I generate the classes using JAXB, the namespace for refered element is wrong.
I mean, the referred element should have kts namespace where as it is having afb namespace.
Because of which validating my XML against this xsd is failing also not able to bind the xml data into the java models.
EX:
afb.xsd :
<xs:import namespace="http://www.boschkts.com" schemaLocation="kts.xsd"/>
<xs:element name="vehicle">
<xs:complexType>
<xs:sequence>
<xs:element ref="vType"/>
<xs:element name="RESULTS" type="kts:RESULTS" >
</xs:sequence>
</xs:complexType>
</xs:element>
kts:xsd :
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.boschkts.com"
targetNamespace="http://www.boschkts.com" elementFormDefault="qualified">
<xs:complexType name="RESULTS">
<xs:sequence>
<xs:element name="SUMMARY" type="SUMMARY" minOccurs="0" />
</xs:sequence>
</xs:complexType>
Vehicle.java :
public class Vehicle {
#XmlElement(namespace = "http://www.boschafb.com", required = true)
protected String vType;
#XmlElement(name = "RESULTS", namespace = "http://www.boschafb.com", required = true)
protected Results results;
}
If I observe the Vehicle.java, the namespace of results property should have been "http://www.boschkts.com" instead of "http://www.boschafb.com"
If I change the namespace manually then binding the data from xml to java models works.
But still validating against the xsd fails with the error :
Caused by: org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'kts:RESULTS'. One of '{"http://www.boschafb.com":RESULTS}' is expected.
Can anybody point what I might be missing in the xsd? or is it the way jaxb generates and I have to modify the classes manually?
Regards,
Satya
I'm assuing your abf.xsd starts with
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.boschafb.com"
targetNamespace="http://www.boschafb.com" elementFormDefault="qualified">
With elementFormDefault set to qualified, all element declarations, even nested ones, belong to the specified target namespace. Note that this applies only to elements, a referenced type does not affect the namespace of the element referencing it.
A solution would be to define an element instead of a type in 'kts.xsd' and referencing this element in your first schema:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.boschkts.com"
targetNamespace="http://www.boschkts.com" elementFormDefault="qualified">
<xs:element name="RESULTS">
<xs:complexType>
<xs:sequence>
<xs:element name="SUMMARY" type="SUMMARY" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.boschafb.com"
targetNamespace="http://www.boschafb.com" elementFormDefault="qualified"
xmlns:kts="http://www.boschkts.com">
<xs:import namespace="http://www.boschkts.com" schemaLocation="kts.xsd"/>
<xs:element name="vehicle">
<xs:complexType>
<xs:sequence>
<xs:element ref="vType"/>
<xs:element ref="kts:RESULT"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Try using an include instead of an import like so:
<xs:include schemaLocation="kts.xsd"/> instead of <xs:import namespace="http://www.boschkts.com" schemaLocation="kts.xsd"/>
This style causes far less problems with intra-namespace includes.

XML Schema: How to specify an attribute with a custom 'simpleType' type?

In my XML schema definition, I'm trying to restrict the value of an attribute to be an integer between 0 and 100.
With reference to the sample schema below, I want attribute 'attr' on element 'root' to have this restriction.
To achieve this I define a simpleType 'Percentage' and set this as the 'type' of 'attr'.
However, my XML schema editor (VS 2008) flags the attribute up as having a problem: "Type 'Percentage' is not declared or is not a simple type".
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" id="test" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://testtttt">
<xs:simpleType name="Percentage">
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="100"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="root">
<xs:complexType>
<xs:attribute name="attr" type="Percentage" use="optional" />
</xs:complexType>
</xs:element>
It looks like you are missing a namespace declaration on your schema root element:
xmlns="http://testtttt"
So the type reference is invalid.

Resources