Reflexive Schema Validation & Definition - xsd

Can can someone help me on how to define a xsd for this.
I also want enforce validation at schema level such that based on the attribute value given, only the corresponding child tags will be displayed (reflexive based on the attribute value).
<?xml version="1.0" encoding="UTF-8"?>
<root>
<sample-tag type="one">
<one></one>
</sample-tag>
<sample-tag type="two">
<two></two>
</sample-tag>
<sample-tag type="three">
<three></three>
</sample-tag>
<sample-tag type="onetwo">
<one></one>
<two></two>
</sample-tag>
</root>

Not possible with XSD. Check if this is possible with Schematron.

If I take your sample XML as an approximation, then strictly speaking there is one way to achieve the effect you want: it is called xsi:type. I personally dislike xsi:type, so I consider this answer rather an academic exercise.
If you agree with this XML:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<sample-tag xsi:type="one">
<one></one>
</sample-tag>
<sample-tag xsi:type="two">
<two></two>
</sample-tag>
<sample-tag xsi:type="three">
<three></three>
</sample-tag>
<sample-tag xsi:type="onetwo">
<one></one>
<two></two>
</sample-tag>
</root>
... then this XSD would give you what you want:
<?xml version="1.0" encoding="utf-8"?>
<!--W3C Schema generated by QTAssistant/W3C Schema Refactoring Module (http://www.paschidev.com)-->
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="root">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="sample-tag" type="sample-tag"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="sample-tag" abstract="true"/>
<xsd:complexType name="one">
<xsd:complexContent>
<xsd:extension base="sample-tag">
<xsd:sequence>
<xsd:element name="one"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="two">
<xsd:complexContent>
<xsd:extension base="sample-tag">
<xsd:sequence>
<xsd:element name="two"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="three">
<xsd:complexContent>
<xsd:extension base="sample-tag">
<xsd:sequence>
<xsd:element name="three"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="onetwo">
<xsd:complexContent>
<xsd:extension base="sample-tag">
<xsd:sequence>
<xsd:element name="one"/>
<xsd:element name="two"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:schema>
If xsi:type is out of question, and XSD 1.1, then you have to go with #Pangea's answer.

Related

UML aggregation/association to XML Schema

long story short:
I want to genererate XSD from UML for this I need a way to represent UML aggregation/association in XSD. I found a mapping an they recommend (for aggregation/association) : "reference element with IDREF attribute and referencing the associated class and keyref for type saftey (key/keyref reference)". But I dont know how to do this exactly because I'm really new in XSD ( < 1 week).
So this is what I thought it should look like but im not sure^^ Does anybody has some advices or can correct if my code has errors?
uml: http://i39.tinypic.com/15x8ufp.png
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="namespace" targetNamespace="namespaceURI">
<xsd:import namespace="namespace" />
<xsd:element name="root">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="classA">
<xsd:complexType>
<xsd:all>
<xsd:element name="attributeElement" />
</xsd:all>
<xsd:attribute name="aId" type="xsd:ID" use="required" />
</xsd:complexType>
<xsd:key name="classAKey">
<xsd:selector xpath="ns:root/ns:classA" />
<xsd:field xpath="#aId" />
</xsd:key>
</xsd:element>
<xsd:element name="classB">
<xsd:complexType>
<xsd:all>
<xsd:element name="refClassA" minOccurs="0" maxOccurs="unbounded"/>
</xsd:all>
<xsd:attribute name="bId" type="xsd:ID" use="required" />
</xsd:complexType>
<xsd:key name="classBKey">
<xsd:selector xpath="ns:root/ns:classB" />
<xsd:field xpath="#bId" />
</xsd:key>
<xsd:keyref name="classARef" refer="ns:classAKey">
<xsd:selector xpath="ns:classB" />
<xsd:field xpath="./refClassA" />
</xsd:keyref>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Perhaps UML For W3C XML Schema Design will help answer your questions. It is old, but the basics of what it shows still apply today and is pretty clearly presented.

Limit value of element to value in other element XSD

Given the following type:
<xsd:complexType name="Options">
<xsd:sequence>
<xsd:element name="option" maxOccurs="unbounded">
<xsd:complexType>
<xsd:all>
<xsd:element name="id" type="xsd:integer" />
<xsd:element name="label" type="xsd:string" />
<xsd:element name="value" type="xsd:string" minOccurs="0" />
<xsd:element name="dependency" type="xsd:integer" minOccurs="0" />
</xsd:all>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
How can I express that a dependency of one option must exist as an id of a different option?
I think I'm supposed to be using xsd:key and xsd:keyref, but having trouble understanding how to use them.
XSD 1.0 doesn't support this. XSD 1.1 supports Conditional Types and assertions which might allow you to do this. For xsd 1.0 you can use Schematron to achieve this.
Constraints can only be expressed in the context of an element.
<?xml version="1.0" encoding="utf-8" ?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="Options">
<xsd:sequence>
<xsd:element name="option" maxOccurs="unbounded">
<xsd:complexType>
<xsd:all>
<xsd:element name="id" type="xsd:integer"/>
<xsd:element name="label" type="xsd:string"/>
<xsd:element name="value" type="xsd:string" minOccurs="0"/>
<xsd:element name="dependency" type="xsd:integer" minOccurs="0"/>
</xsd:all>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="Options" type="Options">
<xsd:key name="PK">
<xsd:selector xpath="option"/>
<xsd:field xpath="id"/>
</xsd:key>
<xsd:keyref name="FK" refer="PK">
<xsd:selector xpath="option"/>
<xsd:field xpath="dependency"/>
</xsd:keyref>
</xsd:element>
</xsd:schema>
If you wish to have this type referenced in multiple instances, along with the constraints you've indicated, then you will have to always define a global element, and then ref that element in your specific contexts.
I would mention that it is very important to understand of your use of the "different" word in your question. If you really mean it, then the above doesn't give you that.

XML Schema Choice - choose at lease one, but no repeat

How can I enforce to chose at lease one, but no repeat?
The following syntax allows any c element to repeat up to 3 times.
<choice minOccurs="1" maxOccurs="3">
<element name="c1" type="string" />
<element name="c2" type="string" />
<element name="c3" type="string" />
</choice>
thnx
steve
Loose the maxOccurs="3" and what you got is "choose at least one", no repeat.
For particles, the default is minOccurs="1"; a mandatory choice, where each option particle is itself mandatory, is your answer.
UPDATE: Based on your comment, if what you're looking is for any ordered combination of the particles you've described, this is the best you can get with XSD spec.
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="root">
<xsd:complexType>
<xsd:choice>
<xsd:sequence>
<xsd:element ref="c1"/>
<xsd:element ref="c2" minOccurs="0"/>
<xsd:element ref="c3" minOccurs="0"/>
</xsd:sequence>
<xsd:sequence>
<xsd:element ref="c2"/>
<xsd:element ref="c3" minOccurs="0"/>
</xsd:sequence>
<xsd:element ref="c3"/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
<xsd:element name="c1" type="xsd:string"/>
<xsd:element name="c2" type="xsd:string"/>
<xsd:element name="c3" type="xsd:string"/>
</xsd:schema>
This is messy already; if you're looking for a greater number of particles or any unordered combination, then I would change the model to something like this (these are XSD 1.0 limitations in action - it all has to do with limitations in the XPath syntax you can use for selectors/fields).
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="root">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="c" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:key name="pk">
<xsd:selector xpath="*"/>
<xsd:field xpath="#code"/>
</xsd:key>
</xsd:element>
<xsd:element name="c" type="TC" abstract="true"/>
<xsd:element name="c1" type="TC1" substitutionGroup="c"/>
<xsd:element name="c2" type="TC2" substitutionGroup="c"/>
<xsd:element name="c3" type="TC3" substitutionGroup="c"/>
<xsd:complexType name="TC">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="code" type="xsd:string"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="TC1">
<xsd:simpleContent>
<xsd:restriction base="TC">
<xsd:attribute name="code" type="xsd:string" fixed="c1"/>
</xsd:restriction>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="TC2">
<xsd:simpleContent>
<xsd:restriction base="TC">
<xsd:attribute name="code" type="xsd:string" fixed="c2"/>
</xsd:restriction>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="TC3">
<xsd:simpleContent>
<xsd:restriction base="TC">
<xsd:attribute name="code" type="xsd:string" fixed="c3"/>
</xsd:restriction>
</xsd:simpleContent>
</xsd:complexType>
</xsd:schema>
A sample XML would like this:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
<c1 code="c1">c11</c1>
<c2 code="c2">c21</c2>
<c3 code="c3">c21</c3>
</root>
or this:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
<c2 code="c2">c21</c2>
<c1 code="c1">c11</c1>
</root>
Basically you're keying in on some component that makes your element unique, that is part of the data as opposed to a tag name. Again, messy, but as an exercise, it may give you an idea.

Any order + constraints for each element

I am trying to create an XSD, which allows child elements to be in any order. But each child element has its own minOccurs and maxOccurs.
My XSD:
<xsd:complexType name="Samples">
<xsd:sequence >
<xsd:element name="Sample1" minOccurs="1" maxOccurs="1">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:boolean" />
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="Sample2" minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:string" />
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
For Example a valid XML:
<Samples>
<Sample2></Sample2>
<Sample1></Sample1>
<Sample2></Sample2>
</Samples>
For Example a not valid XML (Sample1 can be choose only one time):
<Samples>
<Sample2></Sample2>
<Sample1></Sample1>
<Sample2></Sample2>
<Sample1></Sample1>
</Samples>
But i don't know, how i can mix the order, while all elements have its own constraint.
Thanks for help
What if you try this:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Samples">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Sample2" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="Sample1" minOccurs="1" maxOccurs="1"/>
<xsd:element name="Sample2" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Of course, you should add your restrictions to each element:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:complexType name="Sample1Type">
<xsd:simpleContent>
<xsd:extension base="xsd:boolean" />
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="Sample2Type">
<xsd:simpleContent>
<xsd:extension base="xsd:string" />
</xsd:simpleContent>
</xsd:complexType>
<xsd:element name="Samples">
<xsd:complexType>
<xsd:sequence>
<xsd:element type="Sample2Type" name="Sample2" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element type="Sample1Type" name="Sample1" minOccurs="1" maxOccurs="1"/>
<xsd:element type="Sample2Type" name="Sample2" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
OR even shorter for simple types:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Samples">
<xsd:complexType>
<xsd:sequence>
<xsd:element type="xsd:string" name="Sample2" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element type="xsd:boolean" name="Sample1" minOccurs="1" maxOccurs="1"/>
<xsd:element type="xsd:string" name="Sample2" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
P.S.::
There are unfortunately no XSD elements like xsd:sequence, which will allow, what you ask.
What you want looks like xsd:all; however, since xsd:all only works for elements for which maxOccurs is 1, it will not work here. If you can combine choices and sequences to constrain your content, one way to go around duplication of definition (avoid defining twice) is to define Sample1 and Sample 2 as global elements and then ref them under your compositors. If defining global elements is not an option except for your root elements, then you could at least define the types globally - this way you maximize the reuse, and somewhat getting closer to your requirement "without defining twice"...

XSD Make minOccurs depend on containing type

I have a complex type defined which doesn't currently contain any minOccurs restrictions. When I use this comlpex type as an element type I sometimes want the elements to have minOccurs 0, other times 1. E.g.
<xsd:complexType name="Identifier">
<xsd:sequence>
<xsd:element name="Id" type="xsd:string"/>
<xsd:element name="Version" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Wibble">
<xsd:sequence>
<xsd:element name="Id" type="Identifier"/> <!-- I want all elements of Identifier to be mandatory when used as part of a 'Wibble' -->
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Wobble">
<xsd:sequence>
<xsd:element name="Id" type="Identifier"/> <!-- I want all elements of Identifier to be optional when used as part of a 'Wobble' -->
</xsd:sequence>
</xsd:complexType>
Is this possible?
Thanks in advance.
Groups are your friend, e.g.
<xsd:group name="IdentifierGroup">
<xsd:sequence>
<xsd:element name="Id" type="Identifier"/>
</xsd:sequence>
</xsd:group>
<xsd:complexType name="Wibble">
<xsd:sequence>
<xsd:group ref="IdentifierGroup" minOccurs="1"/>
<!-- more elements for Wibble here -->
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Wobble">
<xsd:sequence>
<xsd:group ref="IdentifierGroup" minOccurs="0"/>
<!-- more elements for Wobble here -->
</xsd:sequence>
</xsd:complexType>

Resources