XSD - how to add two 'ref' to the same element - xsd

I have been trying to form this XSD, can someone help please...
I have an element 'country' as below:
<xs:element name="country">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:long" minOccurs="0" />
<xs:element name="isoCode" type="xs:string" minOccurs="0" />
<xs:element name="currencyCode" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
Now, I need to form XSD with two elements, 'source country' and 'destination country' which should both reference to 'country'. Can someone please help me to form that XSD.
<xs:element name="crossCountries">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:long" minOccurs="0" />
<xs:element ref="country" /> <!-- Source Country -->
<xs:element ref="country" /> <!-- Destination Country -->
</xs:sequence>
</xs:complexType>
</xs:element>

You cannot reference an element and assign a different tag name to that reference. What you want to do instead is to define the content model for that element (a complex type would do) and reuse that under differently named tags.
<xs:complexType name="country">
<xs:sequence>
<xs:element name="id" type="xs:long" minOccurs="0" />
<xs:element name="isoCode" type="xs:string" minOccurs="0" />
<xs:element name="currencyCode" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
Then:
<xs:element name="crossCountries">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:long" minOccurs="0" />
<xs:element name="sourceCountry" type="country" /> <!-- Source Country -->
<xs:element name="destinationCountry" type="country" /> <!-- Destination Country -->
</xs:sequence>
</xs:complexType>
</xs:element>

Related

I need one element in xs:all to repeat twice

<xs:complexType>
<xs:all>
<xs:element name="AN" minOccurs="0"/>
<xs:element name="ME" minOccurs="0"/>
<xs:element name="preview" minOccurs="0"/>
<xs:element name="NZ" minOccurs="0"/>
<xs:element name="RE" minOccurs="0"/>
<xs:element name="RU" minOccurs="0"/>
<xs:element name="AU" minOccurs="0"/>
<xs:element name="SE" minOccurs="0"/>
<xs:element name="CM" minOccurs="0"/>
</xs:all>
</xs:complexType>
</xs:element>
In the above code, i want the element "ME" to be used twice in XML and other elements should be used exactly once but in anyorder.
What you want to do is the following. However while this is fine under XSD 1.1, its not under XSD 1.0.
<xs:element name="MyElm">
<xs:complexType>
<xs:all>
<xs:element name="AN" />
<xs:element name="ME" minOccurs="2" maxOccurs="2" />
<xs:element name="preview" />
<xs:element name="NZ" />
<xs:element name="RE" />
<xs:element name="RU" />
<xs:element name="AU" />
<xs:element name="SE" />
<xs:element name="CM" />
</xs:all>
</xs:complexType>
</xs:element>
In XSD 1.0, I'm pretty sure this is not possible. If you can live without them being 'in any order' then you can use a xs:sequence, and if you can live with 0-1 and 0-2 items then you could use a xs:choice. But that's as close as you can get.

Add any to complexType

I have this XML schema:
<xs:element name="lineinfo">
<xs:complexType>
<xs:all>
<xs:element name="done" type="xs:unsignedInt" />
</xs:all>
<xs:attribute name="id" type="xs:long" />
<xs:anyAttribute processContents="skip" />
</xs:complexType>
</xs:element>
but I want to allow any other extra element in the lineinfo tag:
<lineinfo state="assigned" id="175">
<done>4</done>
<todo>6</todo>
</lineinfo>
I tried to add <xs:any /> inside the <xs:all>, but it doesn't seem to be allowed.
I couldn't find a way to do what I wanted, so I ended up adding all "unwanted" tags in my list, with minOccurs set to 0:
<xs:element name="lineinfo">
<xs:complexType>
<xs:all>
<xs:element name="done" type="xs:unsignedInt" />
<xs:element name="todo" minOccurs="0" />
<xs:element name="error" minOccurs="0" />
</xs:all>
<xs:attribute name="id" type="xs:long" />
<xs:anyAttribute processContents="skip" />
</xs:complexType>
</xs:element>
Parent tag of <xs:any> are only choice, sequence. w3cschools #el_any
To use <xs:any> put <xs:sequence> instead of <xs:all>. w3cschools #any
else you could use xs:anyType
xs:anyType is a type, like xs:integer (though xs:anyType is special
in that it can act as a simple or complex type, and it places
essentially no restrictions on the tree that it validates -- think of
it loosely as the Schema language's analog of java.lang.Object).
A sample use would be:
<xsd:element name="value" type="xs:anyType"/>
Anyway if you want use below an example taken from w3cschools #anyattribute
SCHEMA
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
<xs:anyAttribute/>
</xs:complexType>
</xs:element>
<xs:attribute name="gender">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="male|female"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
XML
<person gender="female">
<firstname>Hege</firstname>
<lastname>Refsnes</lastname>
</person>

Restricting an elements that has been extended in XSD

I am trying to create reusable element declarations for a web service to insert and update. I have the following declarations:
<xs:complexType name="commonEntity">
<xs:sequence>
<xs:element name="id" type="snt-common:id" minOccurs="0"
maxOccurs="1" />
<xs:element name="createdByID" type="snt-common:id"
minOccurs="0" maxOccurs="1" />
<xs:element name="createDate" type="snt-common:dateTime"
minOccurs="0" maxOccurs="1" />
<xs:element name="modifiedByID" type="snt-common:id"
minOccurs="0" maxOccurs="1" />
<xs:element name="modifyDate" type="snt-common:dateTime"
minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="contact">
<xs:complexContent>
<xs:extension base="snt-common:commonEntity">
<xs:sequence>
<xs:element name="firstName" type="snt-common:string255"
minOccurs="0" maxOccurs="1" />
<xs:element name="lastName" type="snt-common:string255"
minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element id="update" name="ContactUpdateRequest">
<xs:complexType>
<xs:complexContent>
<xs:restriction base="snt:contact">
<xs:sequence>
<xs:element name="id" type="snt-common:id" minOccurs="1"
maxOccurs="1" />
<xs:element name="modifyDate" type="snt-common:dateTime"
minOccurs="1" maxOccurs="1" />
<xs:element name="firstName" type="snt-common:string255"
minOccurs="0" maxOccurs="1" />
<xs:element name="lastName" type="snt-common:string255"
minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element id="insert" name="ContactInsertRequest">
<xs:complexType>
<xs:complexContent>
<xs:restriction base="snt:contact">
<xs:sequence>
<xs:element name="firstName" type="snt-common:string255"
minOccurs="0" maxOccurs="1" />
<xs:element name="lastName" type="snt-common:string255"
minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:element>
What I am trying to achieve is to create an insert and an update request, both of which are restrictions of contact. Contact in turn is an extension of commonEntity, which is used for all schemas as a base.
Insert works fine since there are no additional restrictions, but for update we require the id and modifyDate (this is how we enforce versioning) in the request. However, I get the following error when validating the schema:
Error for type '#AnonType_ContactUpdateRequest'. The particle of the type is not a valid restriction of the particle of
the base.
It seems as though I cannot restrict elements in the base element, commonEntity. I have tried reordering without success. Is this a nuance of XSD or am I missing something?
Update:
common.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" targetNamespace="http://predictivesolutions.com/schema/common"
xmlns:snt-common="http://predictivesolutions.com/schema/common"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jaxb:extensionBindingPrefixes="xjc" elementFormDefault="qualified"
jaxb:version="2.0">
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings>
<xjc:javaType name="java.util.Calendar" xmlType="xs:dateTime"
adapter="com.ps.snt.ws.util.CalendarDateTimeAdapter" />
<xjc:javaType name="java.util.Calendar" xmlType="xs:date"
adapter="com.ps.snt.ws.util.CalendarDateAdapter" />
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
<!-- Creating this id type to use in the event we need to change to a long,
we can just do it here. -->
<xs:simpleType name="id">
<xs:restriction base="xs:integer">
<xs:minInclusive value="1"></xs:minInclusive>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="dateTime">
<xs:restriction base="xs:dateTime">
<!-- 2013-11-06T11:17:17.043-05:00 -->
<xs:pattern value="\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\d[+\-]\d\d:\d\d" />
<!-- 2013-11-06T11:17:17-05:00 -->
<xs:pattern value="\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d[+\-]\d\d:\d\d" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="string255">
<xs:restriction base="xs:string">
<xs:maxLength value="255" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="commonEntity">
<xs:sequence>
<xs:element name="id" type="snt-common:id" minOccurs="0"
maxOccurs="1" />
<xs:element name="createdByID" type="snt-common:id"
minOccurs="0" maxOccurs="1" />
<xs:element name="createDate" type="snt-common:dateTime"
minOccurs="0" maxOccurs="1" />
<xs:element name="modifiedByID" type="snt-common:id"
minOccurs="0" maxOccurs="1" />
<xs:element name="modifyDate" type="snt-common:dateTime"
minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:schema>
contact.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://predictivesolutions.com/schema/v1_1" xmlns:snt="http://predictivesolutions.com/schema/v1_1"
xmlns:snt-common="http://predictivesolutions.com/schema/common"
elementFormDefault="qualified">
<xs:import namespace="http://predictivesolutions.com/schema/common"
schemaLocation="../common.xsd" />
<xs:complexType name="contact">
<xs:complexContent>
<xs:extension base="snt-common:commonEntity">
<xs:sequence>
<xs:element name="firstName" type="snt-common:string255"
minOccurs="0" maxOccurs="1" />
<xs:element name="lastName" type="snt-common:string255"
minOccurs="0" maxOccurs="1" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!-- For transporting data -->
<xs:element id="contact" name="contact" type="snt:contact">
</xs:element>
</xs:schema>
ContactService.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://predictivesolutions.com/schema/v1_1" xmlns:snt="http://predictivesolutions.com/schema/v1_1"
xmlns:snt-common="http://predictivesolutions.com/schema/common"
elementFormDefault="qualified">
<xs:import namespace="http://predictivesolutions.com/schema/common"
schemaLocation="../common.xsd" />
<xs:include schemaLocation="contact.xsd" />
<!-- Request/Response for inserting data -->
<xs:element id="insert" name="ContactInsertRequest">
<xs:complexType>
<xs:complexContent>
<xs:restriction base="snt:contact">
<xs:sequence>
<xs:element name="firstName" type="snt-common:string255"
minOccurs="0" maxOccurs="1" />
<xs:element name="lastName" type="snt-common:string255"
minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:element>
<!-- Request/Response for updating data -->
<xs:element id="update" name="ContactUpdateRequest">
<xs:complexType>
<xs:complexContent>
<xs:restriction base="snt:contact">
<xs:sequence>
<xs:element name="id" type="snt-common:id" minOccurs="1"
maxOccurs="1" />
<xs:element name="modifyDate" type="snt-common:dateTime"
minOccurs="1" maxOccurs="1" />
<xs:element name="firstName" type="snt-common:string255"
minOccurs="0" maxOccurs="1" />
<xs:element name="lastName" type="snt-common:string255"
minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:schema>

How to use extension in xsd when order of element is important

I have some complexType element which is parent of some element:
<xs:complexType name="elementParent">
<xs:sequence>
<xs:element name="b" type="xs:String" />
<xs:element name="c" type="xs:String" />
</xs:complexType>
now I want to create anothex complex type which will be extension of my parent. Problem is in order. First element should be a then b and then c. I just know this option where order will be b c a which I dont want:
<xs:complexType name="elementChild">
<xs:complexContent>
<xs:extension base="elementParent">
<xs:sequence>
<xs:element name="a" type="xs:String" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:extension> creates a type which is a sequence containing first the base type and then the explicit content defined in <xs:extension>. If you only want to add new elements preceding the elements of another type, you could define the common elements as an <xs:group> and then refer to that group in both of the type definitions.
Something like this:
<!-- common elements defined as a group -->
<xs:group name="elementGroup">
<xs:sequence>
<xs:element name="b" type="xs:string" />
<xs:element name="c" type="xs:string" />
</xs:sequence>
</xs:group>
<!-- group is referred to in element type definitions -->
<xs:element name="elementParent">
<xs:complexType>
<xs:sequence>
<xs:group ref="elementGroup" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="elementChild">
<xs:complexType>
<xs:sequence>
<xs:element name="a" type="xs:string" />
<xs:group ref="elementGroup" />
</xs:sequence>
</xs:complexType>
</xs:element>

How to specify in an XML schema that either one of two fields must be present?

I want to specify that either fieldname or freetext must always be present in XML files that apply to this XSD. Is there a way to do that?
<xs:complexType name="tSome">
<xs:sequence>
<!-- either one of the two below has to be present. -->
<xs:element name="fieldname" type="xs:string" />
<xs:element name="freetext" type="xs:string" />
<!-- this one below must always be present -->
<xs:element name="dbtablename" type="xs:string" />
</xs:sequence>
</xs:complexType>
There is a Choice Indicator in XML Schema, which allows you to take one of the contained elements, but not two or more. If you want any 2 of 3, I suggest doing something like this:
<xs:choice>
<xs:element name="fieldname" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="freetext" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="dbtablename" type="xs:string" minOccurs="0" maxOccurs="1" />
</xs:choice>
<xs:choice>
<xs:element name="fieldname" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="freetext" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="dbtablename" type="xs:string" minOccurs="0" maxOccurs="1" />
</xs:choice>
(Maybe maxOccurs will prevent you from choosing one and the same element twice.)
If that does not work, nothing will I think.
Edited: I didn't correctly understand the question the first time. If you want dbtablename to always be present with any one of fieldname or freetext, then this is the answer:
<xs:complexType name="tSome">
<xs:sequence>
<xs:choice>
<xs:element name="fieldname" type="xs:string" />
<xs:element name="freetext" type="xs:string" />
</xs:choice>
<xs:element name="dbtablename" type="xs:string" />
</xs:sequence>
</xs:complexType>
So, you want either fieldname or freetext and not both? or maybe both? and then dbtablename optionally?
Here is 1 or 2 of the elements:
<xs:choice minOccurs="1" maxOccurs="2">
<xs:element name="fieldname" type="xs:string"/>
<xs:element name="freetext" type="xs:string"/>
<xs:element name="dbtablename" type="xs:string"/>
</xs:choice>
Is this what you want? or did you want dbtablename to be separate?

Resources