4.

Derived Data Types

 

The singularly most significant concept in the world of object-oriented programming is that of 'inheritance'. Here, a basic type is created and then, new types are fashioned out of it by adding to or subtracting from the existing one. By modifying the existing type, the work already accomplished by others in creating the original, can be recycled. The original types too are re-used many times over.

 

To put it simply, the most splendid feature of 'inheritance' or 'extension' is that work or effort put in by other people can be modified and re-used with considerable ease. This greatly adds to our convenience.

 

Let us take a brief detour and discover how to extend or derive one type from another.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:sequence>

<xs:element name="ddd" type="c2"/>

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:complexType name="c1">

<xs:sequence>

<xs:element name="aaa" type="xs:string"/>

<xs:element name="bbb" type="xs:string"/>

</xs:sequence>

</xs:complexType>

<xs:complexType name="c2">

<xs:complexContent>

<xs:extension base="c1">

<xs:sequence>

<xs:element name="ccc" type="xs:string"/>

</xs:sequence>

</xs:extension>

</xs:complexContent>

</xs:complexType>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz>

<ddd>

<aaa> </aaa>

<bbb> </bbb>

<ccc> </ccc>

</ddd>

</zzz>

 

The element ddd is created within the root element zzz with the user-defined type of c2. The 'ref' attribute that we encountered in the earlier chapter generally refers to an existing attribute or element, whereas here, we have used the type attribute, which points to c2.

 

The type c2 is a derived type that extends c1. Hence, initially type c1 is created as a complexType containing the two elements aaa and bbb in a sequence.

 

Then, the type of c2 is created, which again is a complexType. It is followed by the element complexContent. The keyword 'extension' is used in lieu of 'restriction', with the base value of c1. The base attribute clearly signifies that the type is being extended or derived from type c1, which contains the two elements aaa and bbb in a sequence. Another element ccc is created in the sequence to augment the existing two elements.

 

Thus, any element with a type of c2 would now consist of three elements, viz. the elements aaa and bbb from c1 and the element ccc from c2.

 

In the above xml file, the ddd element is furnished with the elements aaa, bbb and ccc below it. No errors are generated.

 

b.xml

<?xml version="1.0"?>

<zzz>

<ddd>

<ccc> </ccc>

<aaa> </aaa>

<bbb> </bbb>

</ddd>

</zzz>

 

Error

Element 'ddd' has invalid child element 'ccc'. Expected 'aaa'. An error occurred at file:///C:/xmlprg/b.xml(4, 2).

 

Since the elements are placed in a sequence, they have to be present in a specific order. The above xml file is bound to generate errors, since the element ccc has been placed at the beginning. Besides, even if a single element is omitted, an error shall surface again. Thus, we have to maintain the same order as specified in the xsd file.

 

In the above xsd file, the element ddd is at the highest level. It has three elements as direct child elements below it, all of which are at the same level. Thus, the elements aaa, bbb and ccc are all at par. There is no way of distinguishing these child elements from one another, with regard to the 'type' that they originate from.

 

 

The same result can also be achieved by making the element ddd hold the three elements in an anonymous complexType. Another possibility is to have a single type c1 consisting of three elements and then, assigning this type c1 to the element ddd. The actual approach adopted in the file has no bearing on the xml file.

 

b.xsd

<xs:extension base="c1">

<xs:sequence>

<xs:element name="aaa" type="xs:string"/>

</xs:sequence>

</xs:extension>

 

b.xml

<?xml version="1.0"?>

<zzz>

<ddd>

<aaa> </aaa>

<bbb> </bbb>

<aaa> </aaa>

</ddd>

</zzz>

 

In the xsd file, the name of the third element is changed from ccc to aaa, but the type is retained as it is. The xml file is also modified so that, instead of the element ccc, the element aaa can be placed after bbb. Thus, even if we employ identical names in the 'derived' or 'extension' class, the XML Schema does not complain.

 

b.xsd

<xs:extension base="c1">

<xs:sequence>

<xs:element name="aaa" type="xs:integer"/>

</xs:sequence>

</xs:extension>

 

Error

Unhandled Exception: System.Xml.Schema.XmlSchemaException: In the same scope elements with the same name have to have the same type. An error occurred at file:///c:/xmlprg/b.xsd(19, 2).

Certain rules have to be complied with at every stage. If we change the type of the new element aaa from string to integer, an exception is hurled at us.

 

The exception clearly construes the fact that the elements can be assigned the same name, as long as the type remains the same. This implies that the schema world acknowledges the difference between the two aaa elements only when they have the same type.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:sequence>

<xs:element name="ddd" type="c3"/>

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:complexType name="c1">

<xs:sequence>

<xs:element name="aaa" type="xs:string"/>

</xs:sequence>

</xs:complexType>

<xs:complexType name="c2">

<xs:complexContent>

<xs:extension base="c1">

<xs:sequence>

<xs:element name="bbb" type="xs:string"/>

</xs:sequence>

</xs:extension>

</xs:complexContent>

</xs:complexType>

<xs:complexType name="c3">

<xs:complexContent>

<xs:extension base="c2">

<xs:sequence>

<xs:element name="ccc" type="xs:string" />

</xs:sequence>

</xs:extension>

</xs:complexContent>

</xs:complexType>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz>

<ddd>

<aaa> </aaa>

<bbb> </bbb>

<ccc> </ccc>

</ddd>

</zzz>

 

The above xsd program may appear to be slightly protracted, but it really is not at great variance from the earlier one. The complexType c1 is created to contain an element aaa, and a complexType c2 is created to accommodate the element bbb. Since c2 extends from the type c1, it effectively contains the two elements aaa and bbb.

 

One more complexType named c3 is created, which has its own element ccc, but it extends c2. The main element ddd is assigned the type c3.

 

The xml file does not generate any error as the three elements of aaa, bbb and ccc have been specified in the correct sequence. It is perfectly valid for one type to derive from another type, which in turn can be derived from another type, and so on. The user is oblivious to this internal structure of the schema.

 

If an element is to be disregarded, the most elementary solution is to make the minOccurs parameter equal to 0. For instance,

<xs:element name="ccc" type="xs:string" minOccurs="0"/>

 

Hereinafter, the existence of the element ccc in the xml file becomes optional.

 

Now, undo the above changes for ccc and assign the minOccurs clause to the element named bbb as follows:

<xs:element name="bbb" type="xs:string" minOccurs="0"/>

 

Now, enter the xml file as below:

 

b.xml

<?xml version="1.0"?>

<zzz>

<ddd>

<aaa> </aaa>

</ddd>

</zzz>

 

Error

Element 'ddd' has incomplete content. Expected 'bbb ccc'. An error occurred at file:///c:/xmlprg/b.xml(5, 3).

 

Granting the 'optional' status to the element of bbb in the xml file does not result in making ccc elective. This is because the type c2 is derived from c1.

 

b.xml

<?xml version="1.0"?>

<zzz>

<ddd>

<ccc> </ccc>

</ddd>

</zzz>

 

Error

Element 'ddd' has invalid child element 'ccc'. Expected 'aaa'. An error occurred at file:///C:/xmlprg/b.xml(4, 2).

 

Placing only the element ccc in the xml file also spawns an error, since the element aaa is conspicuous by its absence. Thus, if an element is made 'default', this action has no link with the other elements that derive from it.

 

b.xml

<?xml version="1.0"?>

<zzz>

<ddd>

<aaa> </aaa>

<ccc> </ccc>

</ddd>

</zzz>

 

On introducing the element aaa in the file, the exception vanishes. Thus, every individual element must have a minOccurs attribute or any other attribute set individually.

 

<xs:extension base="c1" minOccurs="0">

 

Error

Unhandled Exception: System.Xml.Schema.XmlSchemaException: The 'minOccurs' attribute is not supported in this context. An error occurred at file:///c:/xmlprg/b.xsd(16, 26).

 

The minOccurs attribute can neither be set at the extension level, nor at the complexContent level, and also not at the complexType level. The complex type with a name has a default built-in entry for the attribute.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >

<xs:element name="zzz">

<xs:complexType>

<xs:sequence>

<xs:element name="aaa" type="c1" />

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:complexType name='c1'>

<xs:sequence>

<xs:element name='bbb' type='xs:string'/>

</xs:sequence>

</xs:complexType>

</xs:schema>

 

b.xml

<?xml version="1.0" ?>

<zzz>

<aaa>

 <bbb/>

</aaa>

</zzz>

 

In the above xsd file, the types have been re-used. The type c1 has an element bbb, which is assigned to the child element aaa within the root element zzz. Thus, in the xml file, the element aaa can now contain the element bbb.

 

Here, modify the ‘complexType name=c1' statement in the xsd file to contain the 'abstract' attribute as follows:

<xs:complexType name='c1' abstract="true">

On doing so, the following exception is produced:

 

Error

Element 'aaa' is or it's type is abstract. An error occurred at file:///C:/xmlprg/b.xml(3, 2).

The 'aaa' element is not declared. An error occurred at file:///C:/xmlprg/b.xml(3, 2).

The 'bbb' element is not declared. An error occurred at file:///C:/xmlprg/b.xml(4, 2).

 

The error clearly indicates that if complexType c1 is 'abstract', then the type cannot be used directly for any element. The appropriate approach is illustrated in the next program.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:sequence>

<xs:element name="aaa" type="c2"/>

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:complexType name="c1" abstract="true">

<xs:sequence>

<xs:element name="bbb" type="xs:string"/>

</xs:sequence>

</xs:complexType>

<xs:complexType name="c2">

<xs:complexContent>

<xs:extension base="c1">

<xs:sequence>

<xs:element name="ccc" type="xs:string"/>

</xs:sequence>

</xs:extension>

</xs:complexContent>

</xs:complexType>

</xs:schema>

 

b.xml

<?xml version="1.0" ?>

<zzz>

<aaa>

<bbb/>

<ccc/>

</aaa>

</zzz>

 

In the above example, like before, the type c1 is assigned the abstract attribute. Thus, the type cannot be used directly.

 

Now, the type c2 is created. It commences with the complexType type tag, followed by a complexContent element. Then, it uses the 'extension' element to derive from the abstract type c1. Within the sequence element, one more element named ccc is added. Thus, the aaa type contains the two elements aaa, bbb and ccc from the abstract types c1 and c2, respectively.

 

The rationale behind using the 'abstract' type is that it cannot be used directly since it is incomplete. Therefore, the user is compelled to add a few more elements to the existing one. This is akin to using abstract classes in object oriented programming languages.

 

The 'type' attribute can either take a simpleType or a complexType as its value. So, in that sense, the system does not differentiate between them. The complexType can contain any one of the six following types of entities at any given time:

 

·           First is the 'simpleContent' element, which permits the complexType to contain character data or a simpleType, but does not allow any elements.

·           Second is the 'complexContent' element, which only allows elements.

·           Third is the 'group' entity, which permits elements that are referenced from a group.

·           Fourth is the 'sequence' entity, which uses elements in a specified order.

·           Fifth is the 'choice' entity, which allows only one of the elements to be selected.

·           Sixth is the 'all' element, which enables us to use any or all of the elements in any order that we desire.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:sequence>

</xs:sequence>

<xs:choice>

</xs:choice>

</xs:complexType>

</xs:element>

</xs:schema>

 

Error

Unhandled Exception: System.Xml.Schema.XmlSchemaException: The content model of a complex type must consist of 'annotation'(if present) followed by zero or one of 'simpleContent' or 'complexContent' or 'group' or 'choice' or 'sequence' or '

all' followed by zero or more attributes or attributeGroups followed by zero or one anyAttribute. An error occurred at file:///C:/xmlprg/b.xsd(6, 2).

 

In a complexType, a sequence and a choice cannot be present simultaneously.

 

Consequently, the complexType can contain only one of the following six elements: simpleContent, complexContent, group, sequence, choice and all, as has been mentioned in the error.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:sequence maxOccurs="unbounded">

<xs:element name="aaa" type="xs:anyType"/>

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz>

<aaa>aaa</aaa>

<aaa>123</aaa>

</zzz>

 

The element and attribute tag contain a 'type' attribute, which determines the type of content that can be used with the element.

 

Thus, if an element has the type integer, the content between the elements cannot be a string. It has to be an integer. All the simple, complex and built-in types are derived from an abstraction type, which is the base type for all types.

                                                                                               

The type anyType represents the above abstraction. This type does not place any restrictions on the content that can be used. Therefore, the content type is not checked. Thus, whenever the flexibility to use any type of content is desired, the element or attribute uses the 'anyType' type. It can be used wherever the other types are used.

 

b.xsd

<xs:element name="aaa"/>

 

By default, the type is anyType. Thus, if the type has not been specified, the type for the element defaults to anyType.

 

In the earlier examples, it was the Occurs family of attributes that determined the occurrence or frequency of the elements. The next series of programs applies these constraints to a group of elements.

 

The XML Schema allows us to handle a group of elements as a single entity, so that the constraints can be applied to the entire group in a single stroke. In the XML 1.0 world, these were known as 'parameter entities'.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:choice>

<xs:group   ref="bb"/>

<xs:element name="ccc"/>

</xs:choice>

</xs:complexType>

</xs:element>

<xs:group name="bb">

<xs:sequence>

<xs:element name="aaa" />

<xs:element name="bbb"/>

</xs:sequence>

</xs:group>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz>

<aaa>aaa</aaa>

<bbb>123</bbb>

</zzz>

           

In the xsd file, we encounter a new element called 'group'. By using the name attribute, a name is assigned to the group. The task of a group element is to place multiple declarations of elements together, so that they can be assigned to a complexType element concurrently.

 

 

The complexType element is created without a name and then, it is followed by a choice element. In the above example, one can choose between either the group element or the element name ccc. The group element refers to an existing group, which in our case is known as bb. The xml file works fine, since it contains the two elements aaa and bbb from the group bb.

 

b.xml

<?xml version="1.0"?>

<zzz>

<ccc>aaa</ccc>

</zzz>

 

As mentioned earlier, the choice element provides an option of picking one out of the two elements. The xml file works very well when the element ccc is selected instead of the group bb.

 

b.xml

<?xml version="1.0"?>

<zzz>

<aaa>123</aaa>

<bbb>123</bbb>

<ccc>aaa</ccc>

</zzz>

 

Error

Element 'zzz' has invalid child element 'ccc'. An error occurred at file:///C:/xmlprg/b.xml(5, 2).

 

The above xml file contains the group elements as well as the element ccc. This is unacceptable, since the xsd file contains a 'choice' element and not a 'sequence' element. By replacing the 'choice' element with a 'sequence' element, this error gets addressed. But now, the earlier two XML files display errors.

 

The group element

 

A group represents a collection. A group element simply gets replaced with its constituent elements.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:group ref="bb"/>

<xs:attribute name="a1"/>

</xs:complexType>

</xs:element>

<xs:group name="bb">

<xs:sequence>

<xs:element name="aaa" />

<xs:element name="bbb"/>

</xs:sequence>

</xs:group>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz a1="hi">

<aaa>aaa</aaa>

<bbb>aaa</bbb>

</zzz>

 

Since a group is a collection of elements, it tends to make life hassle-free, as there is no further necessity for either a sequence or a choice. The root tag zzz now possesses two elements due to the group element. Bear in mind that the element of attribute a1 following the group, applies to the zzz element.

 

A group contains nothing but the elements. Therefore, placing a set of attribute elements in a group definition would generate an exception. The elements in the group should be used in the same sequence in which they are written. So, exchanging the aaa element with bbb in the xml file is a sure sign of impending disaster.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:sequence>

<xs:group name="bb">

<xs:sequence>

<xs:element name="aaa" />

<xs:element name="bbb"/>

</xs:sequence>

</xs:group>

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:schema>

 

Error

Unhandled Exception: System.Xml.Schema.XmlSchemaException: The 'name' attribute is not supported in this context. An error occurred at file:///c:/xmlprg/b.xsd(5, 12).

 

The above error occurs because a group definition with the complexType element has a local declaration and not a global one. A group can only be created at a global level, and not as the child of anything other than the schema element. In other words, a group definition cannot be 'inlined'. It has to be created globally and then referenced when desired.

 

The all element

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:all>

<xs:element name="aaa"/>

<xs:element name="bbb"/>

</xs:all>

</xs:complexType>

</xs:element>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz>

<bbb>aaa</bbb>

<aaa>aaa</aaa>

</zzz>

 

The 'all' element acts like a group. However, it sternly imposes a restriction on the elements, decreeing that they could either appear once or never. However, there is no established sequence of appearance. Thus, even though the bbb element appears before aaa in the xml file, no exception is generated.

 

There are three attributes that can be used with this element. The first attribute is 'id', which has the same implication everywhere, i.e. it should be unique or different from the rest.

 

The minOccurs attribute represents the minimum number of times that the element must appear. Its value may either be 0 or 1. The default value is 1. Thus, if we eliminate the element aaa from the xml file, an error emanates. In order to banish the error, modify the statement containing the element aa, as shown below.

<xs:element name="aaa" minOccurs="0"/>

 

b.xml

<?xml version="1.0"?>

<zzz>

<aaa>aaa</aaa>

<aaa>aaa</aaa>

<bbb>aaa</bbb>

</zzz>

 

Error

Element 'aaa' cannot appear more than once in an all content model. An error occurred at file:///c:/xmlprg/b.xml(4, 2).

 

The maxOccurs attribute and the minOccurs attribute have default values of 1, implying that the element must occur once and only once. The above xml file generates an error, since the element aaa appears twice. To eradicate the error, add the maxOccurs attribute to the element aaa in the xsd file, as shown here.

 

<xs:element name="aaa" minOccurs="0" maxOccurs="3"/>

Error

Unhandled Exception: System.Xml.Schema.XmlSchemaException: The {max occurs} of all the particles in the {particles} of an all group must be 0 or 1 An error occurred at file:///c:/xmlprg/b.xsd(5, 2).

 

The error is a clear indication that the attribute maxOccurs cannot have a value of 3, since the value must be either 0 or 1. The basic rule encompassing all the elements is that the elements within them may either appear, or they have the option of being completely absent. However, if they do appear, then they cannot occur more than once. The sequence of appearance is flexible.

 

The most important feature of the 'all' element is that it does not enforce any specific order.

 

The 'all' group is a simplified version of the SGML &- Connector. This element can only be positioned at the top level of a content model. The entities contained within it must be individual elements. As pointed out earlier, the elements cannot make more than one appearance. However, it is acceptable if they do not show up at all.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:all>

<xs:element name="aaa" minOccurs="0" />

<xs:element name="bbb" minOccurs="0" />

</xs:all>

<xs:sequence>

<xs:element name="ddd"/>

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:schema>

 

Error

Unhandled Exception: System.Xml.Schema.XmlSchemaException: The content model of a complex type must consist of 'annotation'(if present) followed by zero or one of 'simpleContent' or 'complexContent' or 'group' or 'choice' or 'sequence' or '

all' followed by zero or more attributes or attributeGroups followed by zero or one anyAttribute. An error occurred at file:///c:/xmlprg/b.xsd(8, 2).

 

The rules pertaining to the 'all' group do not extend the liberty of creating elements or sequences outside the 'all' group. The element aaa must appear as the only child at the beginning of the content model. The other restriction is that it can occur only once in a group, but it can occur multiple times in a schema.

 

It can occur with the parent elements of group, extension, restriction and complexType. In our case, the element appears within the complexType. The only elements that can be placed within it are the element and the annotation. Annotation is used primarily for documentation purposes.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz" type="c1">

</xs:element>

<xs:complexType name="c1">

<xs:complexContent>

<xs:extension base="c2">

<xs:all>

<xs:element name="aaa"/>

<xs:element name="bbb"/>

</xs:all>

</xs:extension>

</xs:complexContent>

</xs:complexType>

<xs:complexType name="c2">

<xs:complexContent>

<xs:extension base="c3">

</xs:extension>

</xs:complexContent>

</xs:complexType>

<xs:complexType name="c3">

</xs:complexType>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz>

<aaa />

<bbb />

</zzz>

 

In the above xsd file, the root element is of type c1. Now, merely for the sake of innovation, the end element is placed on a new line, instead of being placed on the same line. Then, a complex type c1 is created, which uses complexContent to extend type c2.

 

This element then ushers in the 'all' element to include the two elements of aaa and bbb, in any sequence.

 

The complexType c2 merely uses complexContent to extend from the type c3, which is devoid of all elements. Incorporate the following changes to the type c2:

 

b.xsd

<xs:complexType name="c2">

<xs:complexContent>

<xs:extension base="c3">

<xs:sequence>

<xs:element name="ccc" type="xs:string"/>

</xs:sequence>

</xs:extension>

</xs:complexContent>

</xs:complexType>

 

Error

Unhandled Exception: System.Xml.Schema.XmlSchemaException: 'all' is not the only particle in a group or being used as an extension. An error occurred at file:///c:/xmlprg/b.xsd(7, 2).

 

In the above program, the element ccc is appended in sequence. The above error crops up because a complexType that uses the 'all' element cannot extend from a complexType that already contains some content.

 

b.xsd

<xs:complexType name="c2">

<xs:sequence>

<xs:element name="ccc" type="xs:string"/>

</xs:sequence>

</xs:complexType>

 

The complexType c2 can be made much simpler than what has been delineated in the earlier case. The main consideration is that no elements or content can be specified in the complexType, if the type that derives from it contains the element.

 

b.xsd

<xs:complexType name="c2">

<xs:attribute name="ccc" type="xs:string"/>

</xs:complexType>

 

However, the presence of an attribute does not trigger any error.

 

b.xml

<?xml version="1.0"?>

<zzz ccc="hi">

<aaa />

<bbb />

</zzz>

 

This attribute applies to the zzz or root element.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:attributeGroup ref="c1"/>

</xs:complexType>

</xs:element>

<xs:attributeGroup name="c1">

<xs:attribute name="a1" type="xs:string"/>

<xs:attribute name="a2" type="xs:string"/>

</xs:attributeGroup>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz a1="hi" a2="bye" />

 

Elements have attributes, but the reverse is not possible. Thus, dealing with groups of elements is considerably distinct from handling groups of attributes.

 

The xsd file starts with the element attributeGroup that is assigned the name c1. Then, two attributes are placed to declare the attributes of a1 and a2.

 

In the element zzz, the attributeGroup element is placed within the complexType, thereby associating two attributes a1 and a2 with the element zzz in one direct shot. The familiar rules about attributes hold good here too, i.e. the attributes are optional and the sequence need not be maintained.

 

The element attributeGroup is created for the attribute group with a name attribute. The element then uses 'ref' to reference the attribute.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:sequence>

<xs:element name="aaa" type="bbb"/>

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:attributeGroup name="c1">

<xs:attribute name="a1" type="xs:string"/>

<xs:attribute name="a2" type="xs:string"/>

</xs:attributeGroup>

<xs:complexType name="bbb">

<xs:attributeGroup ref="c1"/>

</xs:complexType>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz>

<aaa a1="hi" a2="bye"></aaa>

</zzz>

 

The above program is a simple extension of the earlier program. The attributeGroup c1 is created with two attributes of a1 and a2. Then, a complexType bbb is created with the attributeGroup element within it.

 

Using the 'ref' attribute, the element is assigned the attributeGroup c1. Thus, any type that refers to bbb shall contain the two attributes of a1 and a2.

 

The root element aaa contains a complexType and a sequence. Then, an element aaa with the type bbb, is created. Thus, the element aaa now has two attributes, a1 and a2.

 

Change the complexType bbb as follows:

 

b.xsd

<xs:complexType name="bbb">

<xs:sequence>

<xs:element name="ccc" type="xs:string"/>

</xs:sequence>

<xs:attributeGroup ref="c1"/>

</xs:complexType>

 

An element ccc is added under the mandatory 'sequence' element. The correct xml file should read as follows:

 

b.xml

<?xml version="1.0"?>

<zzz>

<aaa a1="hi" a2="bye">

<ccc> no </ccc>

</aaa>

</zzz>

 

This substantiates the fact that an attribute group can be added along with the elements in a complexType. The whole concept behind having attributes within a group is that, it ushers in simplicity and ease of handling a whole group, as against grappling with each attribute individually.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:attributeGroup ref="c2"/>

</xs:complexType>

</xs:element>

<xs:attributeGroup name="c1">

<xs:attribute name="a1" type="xs:string"/>

<xs:attribute name="a2" type="xs:string"/>

</xs:attributeGroup>

<xs:attributeGroup name="c2">

<xs:attributeGroup ref="c1"/>

<xs:attribute name="a3" type="xs:string"/>

</xs:attributeGroup>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz a3="hi" a1="no" a2="yes"/>

 

In the above example, two attributeGroup elements have been created. The attributeGroup c1 has the same attributes of a1 and a2. The second attributeGroup named c2, uses 'ref' to refer to the group c1. It contains one more attribute of c3. Thus, attributeGroup c2 has a total of three attributes, viz. a1, a2 and a3. The root element zzz is then assigned this attribute group of c2.

 

In the xml file, the order of the attributes is of no relevance at all. The above program can be treated as an exercise in recursion.

 

The attributeGroup element takes three attributes, viz. id, name and the ref attribute. It is obvious that the name and the ref attributes cannot occur together. Let us examine the following statement from the above program:

 

<xs:attributeGroup name="c2">

<xs:attributeGroup ref="c1"/>

This statement illustrates that the attributeGroup can possess either the 'name' attribute or the 'ref' attribute.

 

We have already stumbled upon instances where these attributes have been used with the parent elements of attributeGroup, complexType and schema. The elements that fall under these parent elements are 'attribute' and 'annotation'. Thus, the attributeGroup c1 is defined as a child of the schema element.

 

Every attribute is normally assigned a name at the time of creation. The use of the name attribute with attribute and attributeGroup elements has already been examined in the earlier examples.

 

In case the 'ref' attribute is used, it should be present under either of these three, viz. an attributeGroup or a complexType element or anyAttribute. The attributeGroup element cannot have any content. Therefore, it should be empty.

 

The solitary idea of using an attributeGroup is to ameliorate the readability of the schema. The attributeGroup is used in various locations of the schema, as well as in different schemas. Thus, changes have to be incorporated only at one place, which would automatically get reflected in all the group elements that reference them.

 

The attributeGroup can be placed either at the beginning, or at the end of the document.

           

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:sequence>

<xs:element name="aaa" type="xs:string" nillable="true"/>

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz>

<aaa xsi:nil="true"></aaa>

</zzz>

 

Error

Unhandled Exception: System.Xml.XmlException: 'xsi' is an undeclared namespace. Line 3, position 6.

 

The above xml file throws an exception, stating that xsi is an undeclared namespace. In the xsd file, the namespace of xs points to a URI. However, there is no mention of the xsi namespace.

 

To remedy the above error, the xml file has to be modified to contain the following:

 

b.xml

<?xml version="1.0" ?>

<zzz xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<aaa xsi:nil="true"></aaa>

</zzz>

 

Thus, all the errors are eliminated.

The changes are to be introduced to the xml file and not to the xsd file, since the xsi namespace is utilized in the xml file, and not in the xsd file.

 

The next step is to discern the 'nillable' attribute. On numerous occasions, at the time of data entry into a form, certain values that are to be entered are indeterminable. This non-availability of data could be attributed to a number of reasons, such as unknown information or inapplicable information. This unfurnished or unknown data should be represented in a distinguishable manner. While handling databases, the 'null' concept comes into play under such circumstances.

 

In XML, the 'nil' mechanism plays a role analogous to the 'null' concept. Thus, an element can appear with or without a value. This 'nil' mechanism is termed as an 'out of band signal'. Akin to the database methodology, where a field is assigned a value of null, XML too uses the 'nil' attribute to signify that the element has a null value.

 

If the 'nillable' attribute is set to a value of 'true', no content can be added between the elements. The xml file has an element aaa with the attribute called 'nil', which is present in the xsi namespace. Thus, using the 'nillable' attribute in the xsd file is equivalent to creating a nil attribute in the xml file. No errors are visible since no content has been added between the aaa tags.

 

b.xml

<?xml version="1.0" ?>

<zzz xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<aaa xsi:nil="true"> hi </aaa>

</zzz>

 

Error

Element 'aaa' must have no character or element children. An error occurred at file:///c:/xmlprg/b.xml(3, 21).

 

The error witnessed above is inevitable since some content has been inserted between the element aaa. The nil=true categorically implies that the above element has a null value and therefore, must not be assigned any content.

 

On removing the attribute xsi:nil="true", the error vanishes.

<xs:element name="aaa" type="xs:string" />

 

We have removed the attribute nillable=true from the element aaa in the xsd file, as shown above. Further, in the xml file, we have entered the following:

xsi:nil=true"

 

attribute as :

<aaa xsi:nil="true"> hi </aaa>

On doing so, the following error is reported.

 

Error

If the 'nillable' attribute is false in the schema, then the 'xsi:nil' attribute must not be present in the instance. An error occurred at file:///c:/xmlprg/b.xml(3, 2).

 

Thus, the nillable attribute can be used to represent null values for an element. The nil attribute is part of the namespace http://www.w3.org/2001/XMLSchema-instance. To reiterate, the xsi namespace is merely a convention. Any other name too would have sufficed.

 

This nil mechanism applies only to elements and not to attributes, since only an element can have a null value, while simultaneously having attributes containing their own values. Null elements and attributes have no inter-connection whatsoever.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz"/>

<xs:complexType name="c1">

<xs:complexContent>

<xs:extension base="xs:string" />

</xs:complexContent>

</xs:complexType>

</xs:schema>

 

Error

Unhandled Exception: System.Xml.Schema.XmlSchemaException: Undefined complexType 'http://www.w3.org/2001/XMLSchema:string' is used as a base for complex type extension". An error occurred at file:///c:/xmlprg/b.xsd(5, 2).

 

Simple types and complex types cannot be substituted for each other. In a complexType, the complexContent element is used to extend another type using the 'extension' element. While the base attribute requires a complexType, it has been supplied with the simple built-in type of 'string' instead.

 

Thus, an error is reported since simple types and complex types cannot be interchanged with each other.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz">

<xs:complexType>

<xs:sequence>

<xs:element name="aaa" type="c1" />

<xs:element name="bbb" type="c11" />

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:complexType name="c1">

<xs:complexContent>

<xs:extension base="c2" />

</xs:complexContent>

</xs:complexType>

<xs:complexType name="c2">

<xs:attribute name="aa" />

</xs:complexType>

<xs:simpleType name="c11">

<xs:restriction base="c22" />

</xs:simpleType>

<xs:simpleType name="c22">

<xs:restriction base="xs:integer" />

</xs:simpleType>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz>

<aaa aa="hi"/>

<bbb>10</bbb>

</zzz>

 

In the above example, the root tag zzz is followed by a sequence. The sequence offers two elements, viz. aaa and bbb, both of type attribute. The element aaa is of complexType c1, which uses complexContent to extend from type c2, which is also a complexType. This type c2 merely adds the attribute of aa. Therefore, in the xml file, the element aaa is provided with the attribute aa.

 

The element bbb has a type c11, which is a simpleType. This is simply to reaffirm that the type of an element can either be a simpleType or a complexType. In simpleType c11, the restriction is placed on simpleType c22. The type c22 is used as a base. It comprises of an integer. Thus, the element bbb is capable of containing only integers.

 

Here, the string c11 can be used in two situations: Firstly, as a placeholder in the element type bbb, and secondly, while creating the simpleType c11. Now, change the string c11 to c1 as revealed below.

 

b.xsd

<xs:element name="bbb" type="c1" />

<xs:simpleType name="c1">

 

Error

Unhandled Exception: System.Xml.Schema.XmlSchemaException: The SimpleType 'c1' has already been declared. An error occurred at file:///c:/xmlprg/b.xsd(18, 2).

 

The above error is bound to occur since a simpleType and a complexType cannot share the same name. They both use the same namespace to store the names of the types.

 

Thus, occasionally, the XML framework examines whether the type is simple or complex. The framework never permits the creation of a simple and complex type, with both sharing the same name.

 

b.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="zzz" />

<xs:complexType name="c1" />

<xs:simpleType name="c1">

<xs:restriction base="xs:integer" />

</xs:simpleType>

</xs:schema>

 

Error

Unhandled Exception: System.Xml.Schema.XmlSchemaException: The simpleType 'c1' has already been declared. An error occurred at file:///c:/xmlprg/b.xsd(4, 2).

 

The above program is a simplified version of the previous program, which was a long-drawn-out one.