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

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>

Related

Make element required when attribute is set to some value using XSD (1.1)

I have a following schema (1.1). I would like to have schema that will check that a sequence of parameters has mendatory parameter of type '1' and optional parameter of type '2'. I did it using alternatives because different types have different list of attributes.
How write an assertion to check that parameter of type 1 is mendatory?
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" elementFormDefault="qualified" vc:minVersion="1.1">
<xs:element name="rule">
<xs:complexType>
<xs:sequence>
<xs:element name="conditions" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="condition" maxOccurs="unbounded" minOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="parameter" maxOccurs="unbounded" minOccurs="1">
<xs:alternative test="#type = '1'" type="typeOne"/>
<xs:alternative test="#type = '2'" type="typeTwo" />
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="typeOne">
<xs:attribute name="type" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="typeTwo">
<xs:attribute name="type" type="xs:string" use="required" />
</xs:complexType>
</xs:schema>
I did it using alternatives because different types have different list of attributes.
It would be like this:
<xs:element name="condition" maxOccurs="unbounded" minOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="parameter" maxOccurs="unbounded" minOccurs="1">
<xs:alternative test="#type = '1'" type="typeOne"/>
<xs:alternative test="#type = '2'" type="typeTwo" />
</xs:element>
</xs:sequence>
<xs:assert id="type-1-mandatory" test="parameter[#type eq '1']"></xs:assert>
</xs:complexType>
</xs:element>

extending existing complexType

this topic is related to xsd: define an element that can be repeated an even number of times. i would like to create a new complex type using complexContent with extension. i tried this:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xs:complexType name="evenOccurrence">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="B" maxOccurs="2" minOccurs="2"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="oddOcurrence">
<xs:complexContent>
<xs:extension base="evenOccurrence">
<xs:sequence>
<xs:element name="B"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
this code generate the following error: cos-nonambig: B and B (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles.. how i can fix the problem
This are two similar ways of doing it:
1- Without extension:
<xs:complexType name="oddOcurrence">
<xs:sequence>
<xs:element name="B" /> <!-- 1 time -->
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<!-- 2n times -->
<xs:element name="B" maxOccurs="2" minOccurs="2" />
</xs:sequence>
</xs:sequence>
</xs:complexType>
2- Similar, with extension
<xs:complexType name="elementOneTime">
<xs:sequence>
<!-- 1 time -->
<xs:element name="B" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="oddOcurrence">
<xs:complexContent>
<xs:extension base="elementOneTime">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<!-- 2n times -->
<xs:element name="B" maxOccurs="2" minOccurs="2" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
EDIT: ¿Why was it ambiguous?
As evenOccurrence can be empty, when the parser finds the first B element of and oddOccurance, it doesn't know if its parsing the first B of an evenOccurance or the B element that only appears once.
By putting first the element that can only appear once you remove the ambiguity, as the first B element would be analyzed and then the parser would enter in a state in which it would analyze the oddOccurence type (all the other B elements).

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>

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

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>

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