XML schema and problem when deriving from mixed type - xsd

I have following XML schema:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="content" type="contentType"/>
<xs:complexType name="contentType">
<xs:complexContent>
<xs:extension base="versionedElementType">
<xs:sequence>
<xs:element name="item" type="itemType" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="itemType" mixed="true">
<xs:complexContent>
<xs:extension base="itemTypeBase">
<xs:sequence>
<xs:element name="order" type="xs:unsignedInt"/>
<xs:element name="id" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!-- Simple type convert to complex type -->
<xs:complexType name="itemTypeBase" mixed="true">
<xs:simpleContent>
<xs:extension base="itemDescriptionType">
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<!-- Simple type -string restriction -->
<xs:simpleType name="itemDescriptionType" >
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="64"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="versionedElementType">
<xs:attribute name="version" type="xs:string" use="required"/>
</xs:complexType>
</xs:schema>
which I use to validate this XML instance (I want to mix the text in the 'item' element with sub-elements 'order' and 'id'):
<?xml version="1.0" encoding="UTF-8"?>
<content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Content.xsd"
version ="1.0">
<item>Description here...
<order>2</order>
<id>2</id>
</item>
</content>
Whatever I did the validation still says taht there is an error:
The content type of a derived type and that of its base must both be mixed or both be element-only. Type 'itemType' is mixed, but its base type is not.
But I can see that both types - itemType and itemTypeBase are MIXED!!
Thanks a lot
STeN

First of all the error which I see if I open your schema in Visual Studio 2010 is:
The derived type and the based type
must have the same content type.
In you current schema the type itemTypeBase is defined with respect of the <xs:simpleContent> and derived type itemType with the respect of <xs:complexContent> which is not allowed. Either you allow no sub-elements and use <xs:simpleContent> or you do use child elements and use <xs:complexContent>.
I personally don't like and don't use mixed types. If I understand you correct you want to make some restrictions in the text from the content. You want to have the content length between 1 and 64 characters. But <order>2</order>, <id>2</id> and all whitespace, inclusive the new line characters, are also a part of the content. If you want that <item> has simple content, then you can not insert child elements inside.
So the pragmatical solution would be go away from the mixed model and use the XML document in the form
<?xml version="1.0" encoding="utf-8"?>
<content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Content.xsd"
version ="1.0">
<item>
<description>Description here...</description>
<order>2</order>
<id>2</id>
</item>
</content>
where Content.xsd is
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="content" type="contentType"/>
<xs:complexType name="contentType">
<xs:sequence>
<xs:element name="item" type="itemType"
minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="version" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="itemType">
<xs:sequence>
<xs:element name="description" type="itemDescriptionType"/>
<xs:element name="order" type="xs:unsignedInt"/>
<xs:element name="id" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="itemDescriptionType" >
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="64"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
All will be very simple and clear.

Related

cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found

I am trying to understand <any> element in xsd. I had two xsds.
Book Catalogue.xsd
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
<xs:element name="BookCatalogue">
<xs:complexType>
<xs:sequence>
<xs:element name="Book" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Title" type="xs:string" />
<xs:element name="Author" type="xs:string" />
<xs:element name="Date" type="xs:string" />
<xs:element name="ISBN" type="xs:string" />
<xs:element name="Publisher" type="xs:string" />
<xs:any namespace="##any" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Reviewer.xsd
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
<xs:element name="Reviewer">
<xs:complexType>
<xs:sequence>
<xs:element name="Name">
<xs:complexType>
<xs:sequence>
<xs:element name="First" type="xs:string" />
<xs:element name="Last" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
But if i validate the below xml based on above xsd, i am getting cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'p:Reviewer'. error. Does both xsd file should not be in same namespace?
<?xml version="1.0" encoding="UTF-8"?>
<pr:BookCatalogue xmlns:pr="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com AddRequest.xsd ">
<pr:Book>
<pr:Title>pr:Title</pr:Title>
<pr:Author>pr:Author</pr:Author>
<pr:Date>pr:Date</pr:Date>
<pr:ISBN>pr:ISBN</pr:ISBN>
<pr:Publisher>pr:Publisher</pr:Publisher>
<p:Reviewer xmlns:p="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com Children.xsd ">
<p:Name>
<p:First>p:First</p:First>
<p:Last>p:Last</p:Last>
</p:Name>
</p:Reviewer>
</pr:Book>
</pr:BookCatalogue>
Two options...
Option One: If you do not want to have to have the definition of p:Reviewer present, add processContents="lax" to your xs:any element:
<xs:any namespace="##any" minOccurs="0" processContents="lax"/>
Per XML Schema Part 0: Primer Second Edition:
The lax value of the processContents attribute instructs an XML
processor to validate the element content on a can-do basis: It will
validate elements and attributes for which it can obtain schema
information, but it will not signal errors for those it cannot obtain
any schema information.
See also XML Validation in Java: processContents=“lax” seems not to work correctly.
You should also carefully adjust your xsi:schemaLocation values to point to the actual filename of each XSD for each namespace in play. Here is your XML instance with the changes that I made:
<?xml version="1.0" encoding="UTF-8"?>
<pr:BookCatalogue
xmlns:pr="http://www.w3schools.com"
xmlns:p="http://www.w3schools.com/1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com BookCatalogue.xsd http://www.w3schools.com/1 Reviewer.xsd">
<pr:Book>
<pr:Title>pr:Title</pr:Title>
<pr:Author>pr:Author</pr:Author>
<pr:Date>pr:Date</pr:Date>
<pr:ISBN>pr:ISBN</pr:ISBN>
<pr:Publisher>pr:Publisher</pr:Publisher>
<p:Reviewer>
<p:Name>
<p:First>p:First</p:First>
<p:Last>p:Last</p:Last>
</p:Name>
</p:Reviewer>
</pr:Book>
</pr:BookCatalogue>
Note: Make sure that the targetNamespace in Review.xsd matches what's declared for it in BookCatalogue.xml's xsi:schemaLocation attribute.
Option Two: If you do want to insist that the definition of p:Reviewer be present, just make the above changes to be sure that Review.xsd can be found per the xsi:schemaLocation mechanism. No processContents setting is required; it defaults to strict.

Override minoccurs of an element from parent xsd

is it possible to override the minOccurs/maxOccurs attributes of an element in the parent xsd? we can easily extend the parent xsd and create a new xsd with different namespace, but am trying to override with same parent namespace.
Lets say we have an xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:cust="http://test.com/schema/cust" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test.com/schema/cust" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="customer-type">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="hobby" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:element name="customer" type="cust:customer-type"/>
</xs:schema>
can i create extension/restriction of above xsd with same namespace which will restrict/change the <cust:hobby> minOccurs to be 1?
Okay, i was complicating the solution. Before this i was trying to use override function in xml 1.0 which is available only from xml 1.1.
A simple redefine would do the trick:
If the name of your base xsd is cust.xsd then the below redefinition overrides the minOccurs of "hobby" element to 1.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:cust="http://test.com/schema/cust" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test.com/schema/cust" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:redefine schemaLocation="cust.xsd">
<xs:complexType name="customer-type">
<xs:complexContent>
<xs:restriction base="cust:customer-type">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="hobby" type="xs:string" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
</xs:schema>

XSD Schema that JAXB would find acceptable

I have a REST XML response that has a chunk of data like this:
<tag>
<total-pages type="integer">5</total-pages>
<previous-page nil="true"></previous-page>
<next-page nil="true"></next-page>
<offset type="integer">5</offset>
</tag>
Now, sometimes the data can come back like this:
<tag>
<total-pages type="integer">5</total-pages>
<previous-page type="integer">0</previous-page>
<next-page type="integer">1</next-page>
<offset type="integer">5</offset>
</tag>
I have been trying to come up with a XSD schema structure that will account for both possibilities that would be acceptable to JAXB.
I have tried:
<tag>
<total-pages type="numeric-type" />
<previous-page type="numeric-type" />
<next-page type="numeric-type" />
<offset type="numeric-type" />
</tag>
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:integer">
<xsd:attribute type="xsd:string" name="type" use="optional">
<xsd:attribute type="xsd:boolean" name="nil" use="optional">
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
but JAXB blows up with an unmarshalling error.
Thoughts on what XSD schema structure I could use to account for the variability in the returning XML (I cannot change the XML, it is coming from a third-party which I have no control).
Thank you,
Perry
I've started by generating one XSD from your XML samples (two in your case):
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="tag">
<xs:complexType>
<xs:sequence>
<xs:element name="total-pages">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:unsignedByte">
<xs:attribute name="type" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="previous-page">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="type" type="xs:string" use="optional" />
<xs:attribute name="nil" type="xs:boolean" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="next-page">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="type" type="xs:string" use="optional" />
<xs:attribute name="nil" type="xs:boolean" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="offset">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:unsignedByte">
<xs:attribute name="type" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
When you compare with your XSD, you'll notice the use of string instead of integer as the base type. Which explains why you have a problem with unmarshalling: an empty string is not a valid number.
If instead of "nil" you would get an xsi:nil attribute, the XSD would've been generated differently, i.e. it would've had nillable="true" for your elements.
Since you cannot change the XML, then you're stuck with the use of string; alternatively, you could create a union between an empty string and a numeric value... as to how that'll look in JAXB, you can try it...

XML Schema for a fixed element with a fixed attribute?

What would be the correct XML Schema 1.0 declaration for a
<notice xml:lang="en">Banana banana banana</notice>
where:
The xml:lang attribute is compulsory
The value "en" is fixed and compulsory
The content of notice is simple text.
The content of notice is fixed (as above) and compulsory?
My best (but wrong) effort is the following fragment:
<xs:element name="notice" use="required" fixed="Banana banana banana">
<xs:complexType>
<xs:simpleContent>
<xs:extension>
<xs:attribute ref="xml:lang" use="required" fixed="en"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://www.w3.org/XML/1998/namespace" />
<xs:element name="notice" type="notice"/>
<xs:complexType name="notice">
<xs:simpleContent>
<xs:extension base="CONTENT">
<xs:attribute ref="xml:lang" use="required" fixed="en"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="CONTENT">
<xs:restriction base="xs:string">
<xs:enumeration value="Banana banana banana"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

XML Schema Question

Is it possible to define an XML Schema (XSD) to correctly describe a document such as the following?
<root>
<str name="status">success</str>
<str name="message">Your request has been processed successfuly.</str>
</root>
The problem might be that the <str> tags have an attribute (name) as well as string values.
I would be grateful if anyone could come up with an XML Schema for this piece of XML, since I am kind of stuck at this point. My best attempt so far is shown below, but botice that the <str> element cannot have a type (such as xsd:string) in this context.
<xs:element name="object">
<xs:complexType>
<xs:sequence>
<xs:element name="str" minOccurs="2" maxOccurs="2">
<xs:complexType>
<xs:sequence>
<xs:element name="productName" type="xs:string"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
Your constraints are not entirely clear, so a number of schemas would validate the XML depending on how loose/tight you would want the validation to be. This example shows a schema that mandates exactly two elements inside the element and they must have a "name" attribute with the values "status" or "message".
<?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="str" type="StrType" minOccurs="2" maxOccurs="2"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="StrType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="StrAttribute" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="StrAttribute">
<xs:restriction base="xs:string">
<xs:enumeration value="status"/>
<xs:enumeration value="message"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
Of course, this would allow two elements both with the name attribute set to "message", or with "message" first, then status. I believe the schema cannot define a sequence containing two elements of the same name but different types which you would need if you required the validation to ensure that the first always contained "status" and the second one contained "message".

Resources