Including / importing local schemas that have namespaces - xsd

Here is a schema file, midi.xsd that defines a type, note, used to store MIDI note values:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="note">
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="127"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
Here is another schema file, octaves.xsd which uses midi.xsd to help define the layout to be enforced on an XML file containing data about octaves:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="midi.xsd"/>
<xs:element name="octaves">
<xs:complexType>
<xs:sequence>
<xs:element name="octave">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="midi">
<xs:complexType>
<xs:sequence>
<xs:element name="value" type="xs:integer" />
<xs:element name="from" type="note" />
<xs:element name="to" type="note" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="index" type="xs:integer" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
This is fine, and works exactly as you would expect it to, except that I have another requirement: I want note to be in its own namespace, midi, so that
<xs:element name="from" type="note" />
becomes
<xs:element name="from" type="midi:note" />
Try as I might, I cannot get this to work. My attempts have included use of the targetNamespace attribute in various places, the import element, and liberal use of xmlns:midi="...", but to no avail. I'd post one of these attempts here, were it not so cringe-worthy.
Could some kind soul point me in the right direction? I'm pretty sure the problem is to do with the fact that midi.xsd is a local file; it has never been, and never will be, hosted on a web server.

Change midi.xsd to be:
<xs:schema elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetnamespace="/my/midi/namespace">
And then change octaves.xsd to say:
<xs:schema elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:midi="/my/midi/namespace">
<xs:import namespace="/my/midi/namespace" schemaLocation="midi.xsd"/>
...
<xs:element name="from" type="midi:note" />
Note the use of xs:import rather than <xs:include> The two are very different - you use import for bringing in other namespaces, and include for inline inclusion of other schema files into the current namespace.
Note also that /my/midi/namespace can be anything you want, it's an arbitrary identifier.
I'm pretty sure the problem is to do with the fact that midi.xsd is a local file
Nope, not relevant.

Related

XSD circular imports

Is it valid to have two xsd's import each other?
For example, the first one is 'MyService.xsd=48 and it looks like:
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema xmlns:tns="http://documentation" xmlns:ns1="http://documentHistory" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" version="1.0" targetNamespace="http://documentation">
<xs:import namespace="http://documentHistory" schemaLocation="MyService.xsd=49" />
<xs:complexType name="item">
<xs:sequence>
<xs:element name="internalId" type="xs:long" minOccurs="0" />
<xs:element name="readOnly" type="xs:boolean" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="data">
<xs:sequence>
<xs:element name="histories" type="ns1:history" nillable="true" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:schema>
The second xsd is MyService.xsd=49 and looks like:
<?xml version='1.0' encoding='UTF-8'?>
<xs:schema xmlns:tns="http://documentHistory" xmlns:ns1="http://documentation" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" version="1.0" targetNamespace="http://documentHistory">
<xs:import namespace="http://documentation" schemaLocation="MyService.xsd=48" />
<xs:complexType name="history">
<xs:complexContent>
<xs:extension base="ns1:item">
<xs:sequence>
<xs:element name="dateReceived" type="xs:dateTime" minOccurs="0" />
<xs:element name="dateSent" type="xs:dateTime" minOccurs="0" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
Notice that the first one imports the second one and the second one imports the first one. I have an issue that I'm trying to track down and I don't know if this is part of the problem or not. The issue I'm trying to solve has to do with TCL not seeming to parse my wsdl correctly. After TCL parses the wsdl into a dict, the 'history' object doesn't have the properties from the 'item' object, even though the xsd shows that history should extend from item.
The question is: is it valid for two xsd's to import each other or does this look like a problem?
Also, I already looked at this post XSD circular import but found the answer difficult to understand. Any help / insight would be greatly appreciated. Thanks!

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.

XSD my data type

I would like to ask about .XSD document. I cannot find anything about creating my own type, for example:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Client">
<xs:sequence>
<xs:element name="FirstName" type="string"/>
<xs:element name="SecondName" type="string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Contact">
<xs:sequence>
<xs:element name="contacts" type="Client" minOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xsd:schema>
And I would like to know is that right way to define my own type contact?
A few points that were not quite right.
The xsd: namespace alias on the closing schema tag should be just xs:
The primitive string types need there types qualifying, ie xs:string.
From a style point of view ComplexTypes should end Type.
If you want to use the schema (presumably via the Contact) then you need to declare a root element.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML Studio 2012 Developer Edition (Trial) 10.0.1.3941 (http://www.liquid-technologies.com)-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="ClientType">
<xs:sequence>
<xs:element name="FirstName" type="xs:string" />
<xs:element name="SecondName" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ContactType">
<xs:sequence>
<xs:element name="contacts" type="ClientType" minOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:element name="Client" type="ClientType" />
</xs:schema>
Basically XML Schemas are complex things to write without a tool. I'd seriously look into getting a good schema designer, I'd recommend Liquid XML Studio.

XSD: specify a choice must have at least one from a list but no more than one of each

This has been driving me mad for hours. I've read every relevant XSD question on SO and the rest of the Internet it seems and still the answer eludes me.
I need an XML schema that requires at least one of list of elements be present, but each element may appear only 0 or 1 times.
This is similar to this question:
XML schema construct for "any one or more of these elements but must be at least one"
but I was unable to constrain the upper limit: I am apparently using maxOccursincorrectly.
Here's where I left off with my schema:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="Selects">
<xs:sequence minOccurs="2" maxOccurs="4">
<xs:choice>
<xs:element name="aaa" minOccurs="1" maxOccurs="1"/>
<xs:element name="bbb" minOccurs="1" maxOccurs="1"/>
<xs:element name="ccc" minOccurs="1" maxOccurs="1"/>
<xs:element name="ddd" minOccurs="1" maxOccurs="1"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:element name="baseElement">
<xs:complexType>
<xs:sequence>
<xs:element name="MyChoice" type="Selects"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I've tried the minOccurs and maxOccurs on the choice and the element with no luck. Here is XML that validates, though I don't want it to:
<?xml version="1.0" encoding="UTF-8"?>
<baseElement xsi:noNamespaceSchemaLocation="myTest.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MyChoice>
<ddd/>
<ddd/>
</MyChoice>
</baseElement>
Here's an example of what I would like, if possible:
<?xml version="1.0" encoding="UTF-8"?>
<baseElement xsi:noNamespaceSchemaLocation="myTest.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MyChoice>
<ddd/>
<aaa/>
<ccc/>
</MyChoice>
</baseElement>
I would like it to complain about the multiple ddd elements but allow any or all of the others in any order. I get an error if I only have one element under MyChoice so at least something works.
What am I doing wrong? How do I prevent multiple of the same element from validating?
UPDATE
This was my solution (from comments on answer below):
Actually, xs:all did the trick. I swapped the choice for all and added minOccurs="0" maxOccurs="1" to each element. With xs:all, minOccurs must be either 0 or 1 and maxOccurs must be 1. Thanks for your help - I'm good to go now!
Just move the <xs:sequence minOccurs="2" maxOccurs="4"> from around the choice to the point where you want to use it further down. (you can also remove the min/max occurs = 1 as this is what xs:choice does)
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="Selects">
<xs:choice>
<xs:element name="aaa" />
<xs:element name="bbb" />
<xs:element name="ccc" />
<xs:element name="ddd" />
</xs:choice>
</xs:complexType>
<xs:element name="baseElement">
<xs:complexType>
<xs:sequence minOccurs="2" maxOccurs="4">
<xs:element name="MyChoice" type="Selects" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
This validates the following:
<baseElement xsi:noNamespaceSchemaLocation="myTest.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MyChoice>
<bbb></bbb>
</MyChoice>
<MyChoice>
<ccc></ccc>
</MyChoice>
</baseElement>
UPDATE
I think you are reaching the limit of what you can achieve with XSD. I can't see any way you can do this other than by defining a "version" of the MyChoice type for every single combination possible (which will then need different names MyChoice1, MyChoice2 etc)
You can also use xs:all
<xs:complexType name="Selects">
<xs:all minOccurs=2 maxOccurs=4>
<xs:element name="aaa" />
<xs:element name="bbb" />
<xs:element name="ccc" />
<xs:element name="ddd" />
</xs:all>
</xs:complexType>
but this will not prevent you from having four <ddd/>'s

XML schema and problem when deriving from mixed type

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.

Resources