5.

Namespaces

 

The subject of namespace comes to the fore essentially when the tags created by one user need to be differentiated from the tags created by another user. This is achieved austerely by assigning a name to the tags. This name is the namespace prefix, i.e. the name of the namespace. In the earlier programs, we had come across a tag called xs:schema. Here, xs is the name of the namespace prefix, and schema is the tag name.

 

This topic could pack an entire chapter by itself, because every entity that is created in the schema world is always associated with a namespace. This does not hold credence in the DTD world. Thus, the concept of a namespace is of prime importance, since it is the solitary means of differentiating between the tags created by different users. DTDs have no concern with namespaces, since they were invented much before the concept of namespaces was conceived. The word 'namespace' is synonymous with 'namespace prefix'. Thus, for all practical purposes, they can be used interchangeably.

 

For instance, the tag xs:schema is vastly at variance with vijay:schema, because the former stems from the namespace xs, while the latter originates from the namespace vijay. The xs namespace is present somewhere in this big mighty world, and its precise location is revealed by the xmlns:xs 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="xs:string" />

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:schema>

 

b.xml

<?xml version="1.0" ?>

<zzz>

<aaa />

</zzz>

 

The xmlns entity is a reserved word, which is followed by a colon sign. The name of the namespace is specified after the colon. The value assigned to the namespace is known as a Uniform Resource Identifier or URI. It is similar to a URL, though some dissimilarities do exist between them.

 

Very often, the value assigned is http://www.w3.org/2001/XMLSchema . This site contains the rules that are applicable to this namespace. Technically speaking, this is merely a convention and not a rule.

 

If the URI http://www.w3.org/2001/XMLSchema is designated as the default namespace, as has been done in the next program, and then, if a tag is specified without a namespace, it is assumed to belong to the default namespace. Here, the string need not be prefaced by the namespace prefix, since by default, all tags are considered to originate from the default namespace, unless stated otherwise.

 

b.xsd

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

<element name="zzz">

<complexType>

<sequence>

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

</sequence>

</complexType>

</element>

</schema>

 

b.xml

<?xml version="1.0" ?>

<zzz >

<aaa />

</zzz>

 

The above example has been repeated for the sole purpose of clarifying a few intricate notions. The root element zzz has a child element aaa. Now, initiate a few changes in the xsd file as given below.

 

b.xsd

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

<xs:element name="zzz">

<xs:complexType>

<xs:sequence>

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

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:schema>

 

When the attribute targetNamespace is assigned a value of ttt, the following exceptions get generated:

 

Error

Could not find schema information for the element 'zzz'. An error occurred at file:///c:/xmlprg/b.xml(2, 2).

Could not find schema information for the element 'aaa'. An error occurred at file:///c:/xmlprg/b.xml(3, 2).

 

The data type of the targetNamespace is a string that represents a URI reference. This reference is the namespace that all the schema entities eventually relate to. The errors occur in the above case because the element zzz now belongs to the namespace ttt, which has not been implemented in the xml file.  Thus, the xml file has to be modified so that the element zzz originates from the ttt namespace.

 

b.xml

<?xml version="1.0" ?>

<ttt:zzz >

<aaa />

</ttt:zzz>

 

Error

Unhandled Exception: System.Xml.XmlException: 'ttt' is an undeclared namespace.

 

The first thought that crosses the mind is that ttt should be used as a prefix for the element zzz. However, on doing so, an error message is generated, which conveys that it is oblivious to the location of the ttt namespace. Modify the xml file to contain the following statements:

 

b.xml

<?xml version="1.0" ?>

<uuu:zzz xmlns:uuu="ttt">

<aaa />

</uuu:zzz>

 

The reserved xmlns namespace is used to point the prefix uuu to the URI ttt. Since the element zzz belongs to the ttt namespace, we have randomly chosen uuu as the namespace prefix with the URI of ttt. Now, both the targetNamespace and the uuu namespace prefix contain the same URI of ttt. Therefore, no errors are perceived.

 

The namespace URI ttt can now be packed with the types created in the xsd file. In order to refer to these types, the namespace prefix will have to be used to access them. This is akin to using the namespace xs: while referring to the types present in the XML Schema namespace. Thus, the same rules that we conform to currently, have to be observed while referring to the types created in other namespaces.

 

Everything in the XML world relates to a namespace. By specifying a namespace with the targetNamespace attribute, all the types created there on, now belong to the above namespace. Modify the aaa statement in the xml file to the following:

 

b.xml

...

<uuu:aaa />

...

 

Error

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

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

 

The aaa element reports an error when it is prefaced with the namespace prefix uuu. Read on further to lay bare the rationale behind this.

 

A schema is a collection of types and elements that belong to the namespace determined by the targetNamespace attribute. The default value is null. Therefore, in the xml file, it is possible to use the elements and types created in this schema without employing any prefix.

 

Without the targetNamespace attribute, it would be an arduous task to differentiate between types that have the same name, but have been created in different schema files.

 

The targetNamespace attribute identifies the XML Schema vocabulary to which the complexType element belongs. It is a very rudimentary task to create our own complexType element with the targetNamespace attribute set to another target.

 

This target can be completely at variance with the complexType created in the xsd namespace.

 

b.xsd

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

xmlns:vvv="http://www.sonal.com/" targetNamespace="http://www.sonal.com/" elementFormDefault="unqualified" attributeFormDefault="unqualified">

<element name="zzz" type="vvv:c1"/>

<element name="ddd" type="string"/>

<complexType name="c1">

<sequence>

<element name="bbb" type="vvv:c2"/>

<element ref="vvv:ddd" minOccurs="0"/>

</sequence>

</complexType>

<complexType name="c2">

<sequence>

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

</sequence>

</complexType>

</schema>

 

b.xml

<?xml version="1.0"?>

<uuu:zzz xmlns:uuu="http://www.sonal.com/">

<bbb>

<ccc>Mukhi</ccc>

</bbb>

<uuu:ddd> Ha ha </uuu:ddd>

</uuu:zzz>

 

In the above program, the default namespace represents the XML Schema. Hence, the schema and the other tags need not be prefaced. The namespace prefix vvv points to the URI http://www.sonal.com.

 

Thus, elements or types prefaced by vvv belong to the above URI. The targetNamespace is also assigned the same URI. As stated earlier, a URI is similar to a URL.

 

On changing the vvv attribute to www.sonal1.com, the following exception gets thrown:

 

Error

Unhandled Exception: System.Xml.Schema.XmlSchemaException: Type 'http://www.sonal1.com/:c1' is not declared. An error occurred at file:///c:/xmlprg/b.xsd(4, 2).

 

The elementFormDefault and attributeFormDefault are not required since they are set to their default value of 'unqualified'. As is customary, the document starts with the root element zzz, having the type c1. This type consists of an element bbb of type c1, which in turn has the elements ccc and ddd.

 

The element zzz refers to the type as vvv:c1 and not as c1, since the type c1 now belongs to the namespace vvv, which correspondingly points to the URI www.sonal.com. The element bbb also refers to the type as vvv:c2, and not as c2. The second element in the complex type refers to the element name ddd as vvv:ddd.

 

You are requested to undo the errors prior to implementing the new updates. If we transform the type of element zzz from vvv:c1 to c1, the following exception gets thrown:

 

b.xsd

<element name="zzz" type="c1"/>

 

Error

Unhandled Exception: System.Xml.Schema.XmlSchemaException: Type 'http://www.w3.org/2001/XMLSchema:c1' is not declared. An error occurred at file:///c:/xmlprg/b.xsd(4, 2).

 

This error occurs because the system expects the type c1 to originate from the XML namespace, but this is not the way things happen. Remember that xs is the default namespace.

 

In the xml file, only the child elements of the schema zzz and ddd are 'qualified'. The others, such as bbb and ccc, which are part of the complexType c1 and c2, are not qualified by the namespace prefix. If we do qualify them, as seen in the example below, an exception gets thrown.

 

b.xml

<?xml version="1.0"?>

<uuu:zzz xmlns:uuu="http://www.sonal.com/">

<uuu:bbb>

<uuu:ccc>Mukhi</uuu:ccc>

</uuu:bbb>

<uuu:ddd> Ha ha </uuu:ddd>

</uuu:zzz>

 

Error

Element 'http://www.sonal.com/:zzz' has invalid child element 'http://www.sonal.com/:bbb'. Expected 'bbb'. An error occurred at file:///C:/xmlprg/b.xml(3, 2).

The 'http://www.sonal.com/:bbb' element is not declared. An error occurred at file:///C:/xmlprg/b.xml(3, 2).

The 'http://www.sonal.com/:ccc' element is not declared. An error occurred at file:///C:/xmlprg/b.xml(4, 2).

 

The error states that the bbb and ccc elements are not declared. Now, dispose of the uuu prefix from the elements bbb and ccc, and alter the value of the attribute elementFormDefault from 'unqualified' to 'qualified'. On doing so, the following error is generated:

 

b.xsd

elementFormDefault="qualified"

 

Error

Element 'http://www.sonal.com/:zzz' has invalid child element 'http://www.sonal.com/:bbb'. Expected 'bbb'. An error occurred at file:///C:/xmlprg/b.xml(3, 2).

The 'http://www.sonal.com/:bbb' element is not declared. An error occurred at file:///C:/xmlprg/b.xml(3, 2).

The 'http://www.sonal.com/:ccc' element is not declared. An error occurred at file:///C:/xmlprg/b.xml(4, 2).

 

In order to purge the above error, prefix the elements bbb and ccc with uuu. This is reflected in the xml file that ensues.

 

b.xml

<?xml version="1.0"?>

<zzz xmlns="http://www.sonal.com/">

<bbb>

 

<ccc>Mukhi</ccc>

</bbb>

<ddd> Ha ha </ddd>

</zzz>

 

In the above xml file, the attribute elementFormDefault has been set to the value of "qualified". Therefore, every element has to be prefixed with the name of the namespace. In order to evade repetition of this action for each and every element, the default namespace is set to www.sonal.com using the reserved xmlns attribute.

 

Thus, the elementFormDefault is applicable only to the xml file, which employs the elements, and not to the xsd file. The namespace prefix is obligatory, as in vvv:c1.

 

We reiterate that the attribute can be assigned only one of the two values of 'qualified' or 'unqualified'. The default value is 'unqualified'. If the value of 'unqualified' is employed, then the elements from the target namespace, such as bbb and ccc, need not be qualified by the namespace prefix.

 

On the contrary, the value of 'qualified' makes an imposition that the elements in the xml file have to be preceded by the namespace prefix. The names of the namespace prefix are inconsequential, as is amply evident in the xsd file. Here, vvv is used in the XSD file and uuu is used in the xml file. What is of prime significance is the URI, which must be identical in both the cases, or else, an exception will get thrown.

 

The global default value of 'qualified' can be modified, using the form attribute in the element statement.

 

b.xsd

<element name="bbb" type="vvv:c2" form="unqualified"/>

 

Error

Element 'http://www.sonal.com/:zzz' has invalid child element 'http://www.sonal.

com/:bbb'. Expected 'bbb'. An error occurred at file:///c:/xmlprg/b.xml(3, 2).

The 'http://www.sonal.com/:bbb' element is not declared. An error occurred at file:///c:/xmlprg/b.xml(3, 2).

The 'http://www.sonal.com/:ccc' element is not declared. An error occurred at file:///c:/xmlprg/b.xml(4, 2).

 

For the element bbb, the value of the attribute form is set to 'unqualified'. This implies that the name of the element need not be qualified with the namespace prefix. The solitary means of eschewing the error is by knocking off the uuu prefix. Thus, any global level activity can be undone at the individual level.

 

The attributeFormDefault is to attributes what the elementFormDefault is to elements.

 

This attribute provides a direction or a rule for the xml file or the instance document. The rule states that if elements from a particular schema are to be used, the namespace prefix must be specified in the targetNamespace attribute.

 

Now, let us revisit some of the finer aspects of namespaces. The fundamental objective of namespaces is to reference the definitions and declarations that have been created in disparate namespaces.

 

In the above illustration, the elements zzz and ddd are included in the schemas target namespace, whereas the string, the element and the complexType are not prefixed, since they belong to the default xs namespace.

 

The default XML Schema is termed as the 'schema of schemas'. In both the files, viz xml and xsd, the namespace prefix is not as crucial as the URI. The URI need not necessarily point to any physical location. By default, the locally defined elements in the xsd file, such as bbb and ccc, do not require any namespace prefix, as we have seen earlier.

 

The zzz and ddd elements are global elements. They are created as the schema or as the parent element. The bbb and ccc elements are created within the complexType element, and thus, they are its child elements. It is sagacious to create more local elements, since in their case, the xml file does not need a namespace prefix. Also, creation of valid xml files becomes a breeze.

 

Common sense dictates that the root element should be made global, whereas all others should be made local, so that only a single prefix becomes essential. Thus, in the above instance, the ddd element should be made local.

 

The other alternative is to make all the elements global and then, declare the default namespace as the target namespace in the xsd file. This obviates the need for the namespace prefix. The vital point is that you can either make all the elements or only a single element global; anything else would impose an excessive burden on the creator of the xml file.

 

In the next example, all the elements have been made global, so that the namespace prefixes can be completely eluded.

 

b.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:vvv="http://www.sonal.com/" targetNamespace="http://www.sonal.com/">

<element name="zzz" type="vvv:c1"/>

<element name="ddd" type="string"/>

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

<element name="bbb" type="vvv:c2"/>

<complexType name="c1">

<sequence>

<element ref="vvv:bbb"/>

<element ref="vvv:ddd" minOccurs="0"/>

</sequence>

</complexType>

<complexType name="c2">

<sequence>

<element ref="vvv:ccc"/>

</sequence>

</complexType>

</schema>

 

b.xml

<?xml version="1.0"?>

<zzz xmlns="http://www.sonal.com/">

<bbb>

<ccc>Mukhi</ccc>

</bbb>

<ddd> Ha ha </ddd>

</zzz>

 

The above instance is free of errors. The default namespace and the vvv prefix remain unaltered, but the elementFormDefault is eliminated, so that its value remains as 'unqualified'. Then, a global element zzz is created, which refers to the type c1 with the namespace prefix. In turn, this type refers to the two global elements of bbb and ddd.

 

The element bbb refers to the type vvv:c2, which in turn refers to the global element ccc. The point to be noted here is that all the elements are global. Moreover, none of the elements are created in the complexType. Had this been the case, then all the elements so created would have become local instead of global; also, the problems plaguing the namespace prefix would have cropped up here.

 

The xml file has a simple default namespace. Hence, all the elements are global. The only drawback of a global element is that there can be only one instance of such an element, whereas a local element can have multiple instances. The name of a local element includes the name of the element that it belongs to.

 

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="c2" />

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:complexType name="c1">

<xs:sequence>

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

</xs:sequence>

</xs:complexType>

<xs:complexType name="c2">

<xs:sequence>

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

</xs:sequence>

</xs:complexType>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz>

<aaa>

<ccc>Mukhi</ccc>

</aaa>

<bbb>

<ccc>100</ccc>

</bbb>

</zzz>

 

In order to corroborate the above point, the above example has a root element containing two child elements, viz. aaa of type c1 and bbb of type c2. Both these types have the same element ccc, but of type string and integer, respectively.

 

There is no scope for ambiguity, since these elements belong to different types, and they appear under different parents viz. aaa and bbb, respectively. Also, there cannot be two global elements, both named ccc, as there would be no means of distinguishing one from the other.

 

b.xsd

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

xmlns:vvv="http://www.sonal.com/" targetNamespace="http://www.sonal.com/" elementFormDefault="qualified" attributeFormDefault="unqualified">

<element name="zzz">

<complexType>

<attribute name="a1" type="string" form="qualified"/>

</complexType>

</element>

</schema>

 

b.xml

<?xml version="1.0"?>

<zzz xmlns="http://www.sonal.com/" a1="hi" />

 

Error

The 'a1' attribute is not declared. An error occurred at file:///c:/xmlprg/b.xml(2, 36).

 

Attributes conduct themselves in a slightly different manner. In the above file, the root element zzz has an attribute named a1. The targetNamespace is assigned the value of sonal and the attributeFormDefault is specified as 'unqualified'. However, in the case of the attribute a1, the form attribute overrides the value of unqualified, and mandates that the attribute be qualified with the namespace prefix.

 

The error occurs in spite of having the default namespace of www.sonal.com. This occurs because the xmlns attribute for default namespaces applies only to elements and not to attributes. As is evident, the element zzz passes through serenely, but the attribute a1 has to be prefixed with the namespace; in the absence of which, an error is reported.

 

b.xml

<?xml version="1.0"?>

<zzz xmlns="http://www.sonal.com/" xmlns:ttt="http://www.sonal.com/" ttt:a1="hi" />

 

The error flees when a namespace prefix ttt pointing to the URI www.sonal.com is created.

 

Here, the same rules of local and global apply. The XML-Namespaces specification does not assign a default namespace for the attributes. Here, neither an explicit nor an implicit default namespace is applied to the references.

 

 

Schema Definitions across Files

 

b.xsd

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

<xs:include schemaLocation="b1.xsd"/>

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

<xs:complexType name="c1">

<xs:sequence>

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

</xs:sequence>

</xs:complexType>

<xs:complexType name="c3" />

</xs:schema>

 

b1.xsd

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

<xs:complexType name="c2">

<xs:sequence>

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

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

</xs:sequence>

</xs:complexType>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz>

<aaa>

<bbb />

<ccc />

</aaa>

</zzz>

 

As always, the file b.xsd commences with the good old schema element, but without any extra attributes tagging along with it. Then a pristine element called 'include' is introduced, wherein the schemaLocation attribute is initialized to b1.xsd, which is the name of a file. The mission of the 'include' element is to merge the contents specified in the file with the current schema.

 

Thus, the contents of the file b1.xsd can now be accessed in the current schema. The root element zzz in the file b.xsd is of type c1, which in turn contains an element aaa of type c2. There is an empty complexType c3, but there is no type named c2 anywhere in the file b.xsd. However, if you look at the file b1.xsd, it contains a complexType c2, which in turn contains two elements named bbb and ccc. Hence, the file passes through successfully, without any error.

 

While programming, all types are practically placed in a separate file. Then, this file is simply assigned to the 'include' element in the xsd file, as a result of which, all the types are made available to the elements in the file.

 

b1.xsd

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

 

In the b1.xsd file, change the definition of element ccc by assigning it the type c3 instead of xs:string. This does not generate any error even though the xsd file does not contain the type c3. This is because when the system encounters the 'include' element, it simply merges the contents of that file with the current main schema. However, it does not resolve type references initially.

 

Thus, all the types created in b.xsd can be accessed in the file b1.xsd, and vice-versa. We can have an infinite number of 'include' statements placed sequentially in the xsd file. But, ensure that they are not placed after the statement 'element name="zzz"'. Further, they should be located ahead of the 'complexType name="c1"' statement. Nonconformity to these rules would lead to the following exception:

 

Exception

Unhandled Exception: System.Xml.Schema.XmlSchemaException: The include element cannot appear at this location. An error occurred at file:///c:/xmlprg/b.xsd(3, 2).

 

Very often, all the 'include' statements in the xsd file are normally placed at the beginning.

 

<xs:include schemaLocation="b1.xsd"/>

<xs:include schemaLocation="b1.xsd"/>

 

Inclusion of the same file twice does not generate any errors. It appears as though one of them has simply been ignored. Moreover, even if we specify the name of an xsd file that does not exist in the schemaLocation, no error is tossed up.

 

Move the file b1.xsd to the folder, c:\inetpub\wwwroot. This is the root directory for IIS or Personal Web Server. On doing so, the statement given below shall execute flawlessly.

 

b.xsd

<xs:include schemaLocation="http://localhost/b1.xsd"/>

 

b.xsd

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

<xs:include schemaLocation="b1.xsd"/>

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

<xs:complexType name="c1">

<xs:sequence>

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

</xs:sequence>

</xs:complexType>

<xs:complexType name="c3" />

</xs:schema>

 

b1.xsd

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

<xs:complexType name="c2">

<xs:sequence>

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

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

</xs:sequence>

</xs:complexType>

</xs:schema>

 

 

b.xml

<?xml version="1.0"?>

<ttt:zzz xmlns:ttt="sonal">

<aaa>

<bbb />

<ccc />

</aaa>

</ttt:zzz>

 

The file b.xsd has been modified slightly. Firstly, the target namespace is changed to sonal. Then, a namespace prefix vvv is created, which points to the URI sonal. Resultantly, the type c1 now becomes vvv:c1. Also, unlike the earlier example, there is no default namespace in the file.

 

The file b1.xsd remains unaltered, except for the namespace, which now points to sonal. Although it may be redundant, its presence in the file does not cause any tribulations. Moreover, since the namespace is vvv, the type c2 is referred to as vvv:c2 in the file b.xsd.

 

Since zzz is a global element in the xsd file, the newly created namespace prefix ttt has to be attached only to the zzz element in the xml file.

 

If the targetNamespace attribute is changed to sonal1 in the schema element within the b1.xsd file, an exception is generated. This stems from the fact that the 'include' element can include a file only if it originates from the same namespace.

 

In a case where the namespaces are dissimilar; i.e. one is sonal from the file b.xsd, while the other is sonal1 from the file b1.xsd, the include fails. This happens because the 'include' statement cannot possibly include anything from a schema that contains another namespace. To circumvent the above obstacle, the 'import' statement can be used in place of the 'include' statement. The 'import' statement is equipped to handle diverse namespaces.

 

Schemas spread over multiple files result in ease of maintenance as they restrict access and also enhance readability. Thus, all type declarations should be placed in their own files.

 

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="c1" />

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:complexType name="c1">

<xs:sequence>

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

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

</xs:sequence>

</xs:complexType>

<xs:complexType name="c2">

<xs:complexContent>

<xs:extension base="c1">

<xs:sequence>

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

</xs:sequence>

</xs:extension>

</xs:complexContent>

</xs:complexType>

<xs:complexType name="c3">

<xs:complexContent>

<xs:extension base="c1">

<xs:sequence>

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

</xs:sequence>

</xs:extension>

</xs:complexContent>

</xs:complexType>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz>

<aaa>

<ccc />

<ddd />

</aaa>

<bbb>

<ccc />

<ddd />

</bbb>

</zzz>

 

This program indeed is a long drawn out one, but nonetheless, it is interesting and useful.

 

The root tag zzz contains two child elements aaa and bbb, both of which have the same user defined complexType c1. Thus, both aaa and bbb embody identical content that is contained in the type c1, viz. the elements ccc and ddd.

 

The complexType c2 commences with a complexContent element and then, it extends the type c1. It also appends a fresh element eee to the two existing elements ccc and ddd that come from the extended type.As a result, the type c2 has three elements, viz. bbb, ccc and eee.

 

Following the same modus operandi, we create a type c3, which also extends from type c1 and adds an element fff. Thus, the complexType c3 has three elements, viz. ccc, ddd and fff. For the time being, the types c2 and c3 are not being used at all.

 

The xml file contains two child elements aaa and bbb, which correspondingly contain the tags ccc and ddd. Therefore, no errors are visible. After all, all's well that ends well!

 

b.xml

.....

<aaa>

<ccc />

<ddd />

<eee />

</aaa>

...

 

Error

Element 'aaa' has invalid child element 'eee' . An error occurred at file:///c:/xmlprg/b.xml(6, 2).

The 'eee' element is not declared. An error occurred at file:///c:/xmlprg/b.xml(6, 2).

 

However, adding the element eee within element aaa in the xml file b.xml, generates the above error. This is apparent since there is no element named eee in type c1. In fact, it is present in type c2.

 

b.xml

<?xml version="1.0"?>

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

<aaa xsi:type="c2">

<ccc />

<ddd />

<eee />

</aaa>

<bbb xsi:type="c3">

<ccc />

<ddd />

<fff />

</bbb>

</zzz>

 

The namespace prefix xsi is added to the xml file, and it points to its URI. Thereafter, in the element aaa, the type attribute from the xsi namespace is initialized to the type c2. This act permits the use of element eee in the element aaa. Similarly, the type attribute in the bbb element is initialized to c3. Thus, the addition of the fff element springs no error.

 

You would surely appreciate that it is easy to dynamically change the run type of the element as follows:

* From c1 to c2 in the case of element aaa.

* From c1 to c3 in the case of element bbb.

 

b.xsd

...

<xs:complexType name="c3">

<xs:sequence>

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

</xs:sequence>

</xs:complexType>

...

 

Error

Element 'bbb' has xsi:type derivation blocked. An error occurred at file:///c:/xmlprg/b.xml(8, 2).

 

On rewriting the complexType c3 as shown in the preceding program, the above error is reported. The error lucidly apprizes us that unless the type is 'extended', the use of xsi:type is forbidden.

 

To sum it up, an element can be derived from a certain type c1. Then, in the xml file, its type can be altered to another type by using the xsi:type attribute. This modification is possible only if the type that is used extends from the type c1, from which the element was originally created.

 

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="ccc" type="xs:string"/>

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

</xs:sequence>

</xs:complexType>

<xs:complexType name="c2">

<xs:complexContent>

<xs:extension base="c1">

<xs:sequence>

<xs:element name="eee" 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="fff" type="xs:string"/>

</xs:sequence>

</xs:extension>

</xs:complexContent>

</xs:complexType>

</xs:schema>

 

b.xml

<?xml version="1.0"?>

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

<aaa xsi:type="c3">

<ccc />

<ddd />

<eee />

<fff />

</aaa>

</zzz>

 

In the above example, the element aaa has a type of c1, which contains the two elements ccc and ddd. Then, the type c2 is created, which extends c1 and also encloses the element eee. In addition to this, another type c3 is created, which now extends the type c2. The type c3 thus represents four child elements viz. ccc, ddd, eee and fff.

 

In the xml file, the type attribute is initialized to the type c3, and not to c2. No error is reported since the type c2 in turn extends type c1. Thus indirectly, type c3 extends type c1. This is perfectly valid since the final type is c1.

This feature is visible where the base type is an Address.  The type contains fields that comprise of addresses. Then, a distinctive type, enclosing the unique types that extend this base type, can be created for each country. This is a perfect instance of a base type and a derived type.

 

The derived type is utilized either in the xml file or in the instance document, by implementing the xsi:type attribute.

 

b.xsd

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

<xs:element name="zzz" />

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz />

 

In the above xsd file, the xs prefix as well as the xs1 prefix, both point to the same URI. Further, the default namespace also points to it. Despite considerable redundancy, no errors are reported.

 

b.xsd

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

<xsd1:element name="zzz" />

</schema>

 

Error

Unhandled Exception: System.Xml.XmlException: The 'xs:schema' start tag on line '1' doesn't match the end tag of 'schema' in file 'file:///c:/xmlprg/b.xsd'. Line 3, position 3.

 

The use of xs1, or the absence of a namespace prefix in the xsd file, is legally permissible. But, commencing the schema element with an xs prefix and ending it without a prefix is not allowed, even though the default prefix is the XML Schema URI. Therefore, the above error is reported. The only rationale for this could be that the XML world is a stickler for rules.

 

Whenever a namespace prefix is omitted, the default namespace is referred to. This signifies that every schema belongs to some namespace or the other.

 

The targetNamespace attribute is used to set the value of the default namespace.

 

b.xsd

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

<xs:element name="zzz" />

</xs:schema>

 

b.xml

<?xml version="1.0"?>

<zzz />

 

No errors are perceived, even when the attribute elementFormDefault is specified as 'qualified' and the instance document or xml file do not use it. This is because the targetNamespace has a default value of null, i.e. an empty string.

 

Rewriting the above line as depicted in

 

b.xsd

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

 

would accomplish the same result, since the targetNamespace is an empty string. However, modifying the tagetNamespace to hold a space, as demonstrated in

 

b.xsd

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

 

throws the following exception

Error

Unhandled Exception: System.Xml.Schema.XmlSchemaException: TargetNamespace '  ' is invalid URI. An error occurred at file:///c:/xmlprg/b.xsd(1, 2).

 

The XML world strictly abides by its rules. The specifying of spaces as the value of the URI generates the above error, because the file does not adhere to the rules related to the naming of a URI.

 

In the instance document, whether the elementFormDefault attribute has been used or not, is insignificant, since all the elements get validated anyway. This attribute merely saves us the hassle of qualifying all the elements or just the global elements.

 

Let us now cast a fleeting glance at the virtues and weaknesses of specifying the elementFormDefault as qualified or unqualified. If the elementFormDefault is specified as unqualified, then only the global elements have to be qualified in the instance document. The complexities governing the namespaces in the xsd file are entirely concealed.

 

However, problems arise when changes are made to the schema, such as making the local declarations as global. In such cases, the instance document, i.e. the xml file must adapt to these changes. On the other hand, assigning the value of qualified to the attribute elementFormDefault mandates that all elements in the instance document must be qualified.

 

The silver lining is that the instance document is impervious to any changes made in the local or global declarations. However, the user gets exposed to the namespace complexities.

 

One of the harsh realities of life is that, there is nothing like a perfect solution. So, it is left to each individual to decide for himself as to which of the two options of 'qualified' and 'unqualified', is a better bet for the elementFormDefault attribute.