XML Schema same attributes names but different specific attribute sets of values? - xsd

I wish to create a repeating same named element with two attributes for which the values of each are tied to each other. i.e.
<anElement id="R1" description="Some definition for R1"/>
<anElement id="R2" description="Some definition for R2"/>
Ideally I would define "groups" of id and description attributes together and reference one of the groups for each instance of anElement element.
<complexType name="RElements">
<choice>
<element name="anElement" type="R1Group"/>
<element name="anElement" type="R2Group"/>
</choice>
</complexType>
<complexType name="RElementsType">
<sequence>
<element ref="RElements" minOccurs="1" maxOccurs="unbounded"/>
</sequence>
</complexType>
But Choice doesn't allow multiples of the same element name. I see discussions about how to have multiple elements of the same name but none allow additional attributes let alone having attributes tied to each other. The only way that I can get close is by having a different named element based on the id. i.e.
<R1 id="R1" description="Some definition for R1"/>
<R2 id="R2" description="Some definition for R2"/>
Any suggestions?

You need to provide more information.
Basically to achieve the XML you have provided a simple schema like this would suffice.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2015 Developer Bundle Edition 13.0.3.5737 (http://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="RootElement">
<xs:complexType>
<xs:sequence>
<xs:element name="anElement" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" type="xs:string" />
<xs:attribute name="descritpion" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
However you mention that the attribute values id and description are linked, you may be able to constrain these, but you need to provide more info. Also I'm not sure why you are looking at choices? Its difficult to see what your attempting give you only provide snippets of the schema
To include the constraints described in later comments the following schema would allow this, but force a change in the XML structure
<AnElement id="E1"> Exterminator serial <ref id="E1"/> </AnElement>
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid XML 2015 Developer Bundle Edition 13.0.0.5686 (http://www.liquid-technologies.com)-->
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="RootElement">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="AnElement">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="ref" minOccurs="0">
<xs:complexType>
<xs:attribute name="id" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:string" use="optional" />
</xs:complexType>
<xs:key name="IDVal">
<xs:selector xpath="." />
<xs:field xpath="#id" />
</xs:key>
<xs:keyref name="IdRef" refer="IDVal">
<xs:selector xpath="ref" />
<xs:field xpath="#id" />
</xs:keyref>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

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.

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.

Why won't XML Schema allow me to define a one-to-many key? And how do I do so?

I'm falling over on a frustrating, arbitrary restriction in XML Schema. For some reason, it insists that PK-FK relationships have to be one-to-one. Why?
For example, given the schema:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="FutureSchema"
targetNamespace="http://tempuri.org/FutureSchema.xsd"
elementFormDefault="unqualified"
xmlns="http://tempuri.org/FutureSchena.xsd"
xmlns:mstns="http://tempuri.org/FutureSchema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="FUTUREFILE">
<xs:complexType>
<xs:sequence>
<xs:element name="Configuration">
<xs:complexType>
<xs:sequence>
<xs:element name="Experiments">
<xs:complexType>
<xs:sequence>
<xs:element name="Experiment">
<xs:complexType>
<xs:attribute name="ID" type="xs:integer"/>
<xs:attribute name="Profile" type="xs:integer"/>
</xs:complexType>
<xs:keyref name="dummy" refer="LP">
<xs:selector xpath="Experiment"/>
<xs:field xpath="#Profile"/>
</xs:keyref>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:key name="LP">
<xs:selector xpath="*/Configuration/Profiles/Profile"/>
<xs:field xpath="#ID"/>
</xs:key>
</xs:element>
<xs:element name="Profiles">
<xs:complexType>
<xs:sequence>
<xs:element name="Profile">
<xs:complexType>
<xs:attribute name="ID" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
And an example instance:
<?xml version="1.0" encoding="utf-8" ?>
<b:FUTUREFILE xmlns:b="http://tempuri.org/FutureSchena.xsd">
<Configuration>
<Experiments>
<Experiment ID="1" Profile="1"/>
<Experiment ID="2" Profile="1"/>
</Experiments>
<Profiles>
<Profile ID="1"/>
</Profiles>
</Configuration>
</b:FUTUREFILE>
Document validation throws an error if I define <Experiment ID="1" FK="1"/><Experiment ID="2" FK="1"/>, for example; i.e. more than one Experiment may not reference the same Profile. But why else would I want to use a key relationship? What use is a key relationship at all if I can't do something so fundamental?
OK, if and won't let me do this, how should I?
edit #1: As requested, I've padded out my code sample to include the full schema and a basic instance.
edit #2: Interesting. SharpDevelop's XML editor (as opposed to Visual Studio's) doesn't seem to object. It doesn't object to the foreign key value referring to a nonexistent primary key either (which IMO it should) but it's a start.
What wasn't clear ?... My english, it's all :-)
Some remarqs, I'm not sure it's solution :
In exemple instance, it's best to use xmlns:b="http://tempuri.org/FutureSchema.xsd">, and not xmlns:b="http://tempuri.org/FutureSchena.xsd"> (n -> m).
Also it's best to put b: in front of all elements names.
According to your schema, you can't have two Experiment in Experiments, only one.
On xsd, put <xs:keyref name="dummy" refer="mstns:LP">, that works best for me ; it's because xpath expression doesnt't understand default namespace, see Correct way to use key in xsd.

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.

XSD for an element that must have an attribute depending on another attribute value

I have a <font> tag having attributes name required , link='notusing' required and replaced_with (it should be optional only link value is not a string of 'notusing').
Also XSD has to check whether the xml has font with a name that is specified in replaced_with.
Example:
<fonts>
<font name='font1' link='inuse'/>
<font name='font2' link='inuse'/>
<font name='font3' link='notusing' replaced_with="font2"/>
</fonts>
How can i write the XSD for this? Thanks
I don't think it's possible to enforce that replaced_with can only occur if link='notusing'. You can make replaced_with optional using minOccurs='0', but that's about it.
If you are able to change the structure of the XML file, you could do something like this instead:
<?xml version="1.0" encoding="utf-8" ?>
<fontData
xmlns="someNamespace"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="someNamespace XMLSchema1.xsd">
<fonts>
<font name="font1" />
<font name="font2" />
</fonts>
<obsoleteFonts>
<font name="font3" replaced_with="font2" />
</obsoleteFonts>
</fontData>
And then you could use key and keyref to enforce that the name of any font within obsoleteFonts exists in fonts.
Here's how the XSD file would look to enforce this XML format:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
xmlns="someNamespace"
xmlns:tns="someNamespace"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="someNamespace"
elementFormDefault="qualified">
<xs:element name="fontData" type="fontData">
<xs:key name="fontKey">
<xs:selector xpath="tns:fonts/tns:font" />
<xs:field xpath="#name" />
</xs:key>
<xs:keyref name="obsoleteFontToFontKeyRef" refer="fontKey">
<xs:selector xpath="tns:obsoleteFonts/tns:font" />
<xs:field xpath="#replaced_with" />
</xs:keyref>
</xs:element>
<xs:complexType name="fontData">
<xs:sequence>
<xs:element name="fonts" type="fonts" />
<xs:element name="obsoleteFonts" type="obsoleteFonts" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="fonts">
<xs:sequence>
<xs:sequence>
<xs:element name="font" type="font" maxOccurs="unbounded" />
</xs:sequence>
</xs:sequence>
</xs:complexType>
<xs:complexType name="obsoleteFonts">
<xs:sequence>
<xs:sequence>
<xs:element name="font" type="obsoleteFont" maxOccurs="unbounded" />
</xs:sequence>
</xs:sequence>
</xs:complexType>
<xs:complexType name="font">
<xs:attribute name="name" type="xs:string" />
</xs:complexType>
<xs:complexType name="obsoleteFont">
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="replaced_with" type="xs:string" />
</xs:complexType>
</xs:schema>
I tested this with the Visual Studio schema validator, but hopefully it will work properly in whatever technology you are using.
In XML schema (XSD), you cannot express this kind of requirement / restriction. XML schema is all about structure, and you cannot use values of elements or attributes to influence the structure of other elements or attributes. Can't be done, it's just not part of the XML schema standard.
If you need this kind of checks, have a look at Schematron, a different kind of XML validation framework.

Resources