- The Utility of Namespaces
- The Schema Namespace
- Target Namespaces
- The XML Schema Instance Namespace
- Namespace Issues with Multipart Schemas
Namespace Issues with Multipart Schemas
There are two ways to build a single schema from multiple parts. One is by using the include element, and the other is by using the import element. However, because of the potential for conflicting element/attribute declarations, namespaces play a very important role when building a multipart schema.
When using an include to build a multipart schema, both the including and the included schema must be part of the same target namespace. So, if we were building a writing-instruments.xsd schema and importing our pen.xsd schema, we would have the following:
<?xml version="1.0" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.mycompany.com/Pen"> <xs:element name="writing-instruments"> <xs:element ref="pen" maxOccurs="unbounded"> </xs:element> </xs:schema>
This allows us to use the Pen elements within our writing instruments document, because both are a part of the same targetNamespace. However, since writing instruments should also include pencils, which are part of another namespace, we'll need to use the import mechanism instead:
<import targetNamespace="http://www.mycompany.com/Pen" schemaLocation="http://www.mycompany.com/pen.xsd">
The import element allows us to import another schema, by location, along with the associated namespace. We can then build the new schema, complete with xmlns attributes to define the proper prefixes:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:pen="http://www.mycompany.com/Pen" xmlns:pencil="http://www.mycompany.com/Pencil" targetNamespace="http://www.mycompany.com/Writing-Instruments">
Then we are free to use the element declarations in the imported schemas within our new schema:
<xs:element ref="pen:pen" minOccurs="0" maxOccurs="unbounded">
The result is a writing-instruments.xsd schema that defines one namespace while importing two others, which allows us to avoid the possibility of namespace collisions in the final XML instance document:
<?xml version="1.0" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:pen="http://www.mycompany.com/Pen" xmlns:pencil="http://www.mycompany.com/Pencil" targetNamespace="http://www.mycompany.com/Writing-Instruments"> <import targetNamespace="http://www.mycompany.com/Pen" schemaLocation="http://www.mycompany.com/pen.xsd"> <import targetNamespace="http://www.mycompany.com/Pencil" schemaLocation="http://www.mycompany.com/pencil.xsd"> <xs:element name="writing-instruments"> <xs:element ref="pen:pen" minOccurs="0" maxOccurs="unbounded"> <xs:element ref="pencil:pencil" minOccurs="0" maxOccurs="unbounded"> </xs:element> </xs:schema>
Namespace use may seem complicated, as it tends to clutter the XML code in XML Schemas and instance documents. However, namespaces are really just a matter of keeping track of which elements/attributes go with which namespaces, and with a little attention to detail don't need to be all that intimidating.
Next in this series we'll take a look at datatypes, including how XML Schemas provide primitive and derived datatypes, and the mechanisms for defining your own datatypes.