Namespace Tutorial

When working with XML Schemas, you will eventually run into namespace issues. The good point about namespaces is that this allows you to pull modules from anywhere on the internet, and to keep them separate. The cost for this capability is some complexity that must be understood and dealt with.

The problem comes in two guises. The first is that namespaces must be understood in terms of the XML Schemas Specification/Recommendation. Some good readings for this are the XML Schema Primer and the XML Best Practices.

However, there is yet another problem. The implementations don't always give you the full range of capabilities that are allowed in the specification. Thus, it may take some experimentation to get something that works with a particular implementation.

For reference, I have been using the online validator: XML Schema Validator, being developed by the University of Edinburgh.

Specific Usage for POSC Modules

The POSC modules are all physically located in http://www.posc.org/schemas. They all contain a target namespace with the same name:

  targetNamespace="http://www.posc.org/schemas"
In addition, the files are given with either elementFormDefault="qualified" or elementFormDefault="unqualified" until it is determined which is preferable. By using the qualified or unqualified files, we will be able to develop schemas with different XML outputs. The ultimate question is which is the desired output.

It is assumed that an application schema will be developed in a different namespace using one or more modules from http://www.posc.org/schemas. These will be imported into the schema to be combined with the rest of the schema definitions.

The four cases

Four cases will be considered - two for unqualified, and two for qualified. The sample files and the names by which they will be known are shown in the following table (Details of the root element tag are suppressed in order to more clearly see the differences):

Simple unqualified.
<my:RootElement>
  <UnitsDefinition>
    <UnitOfMeasure uid="m" acronym="m"/>
    <UnitOfMeasure uid="ft1" acronym="ft US">US Survey Foot
      <ConversionToBaseUnit baseUnit="m">
        <numerator>12</numerator>
        <denominator>39.37</denominator>
      </ConversionToBaseUnit>
    </UnitOfMeasure>
  </UnitsDefinition>
  <distanceFromWell uom="m">899</distanceFromWell>
  <depthOfWell uom="ft1">12994</depthOfWell>
</my:RootElement>
Simple qualified.
<RootElement>
  <UnitsDefinition>
    <UnitOfMeasure uid="m" acronym="m"/>
    <UnitOfMeasure uid="ft1" acronym="ft US">US Survey Foot
      <ConversionToBaseUnit baseUnit="m">
        <numerator>12</numerator>
        <denominator>39.37</denominator>
      </ConversionToBaseUnit>
    </UnitOfMeasure>
  </UnitsDefinition>
  <distanceFromWell uom="m">899</distanceFromWell>
  <depthOfWell uom="ft1">12994</depthOfWell>
</RootElement>
Complex unqualified
<my:RootElement >

  <UnitsDefinition>
    <UnitOfMeasure uid="m" acronym="m"/>
    <UnitOfMeasure uid="ft1" acronym="ft US">US Survey Foot
      <ConversionToBaseUnit baseUnit="m">
        <numerator>12</numerator>
        <denominator>39.37</denominator>
      </ConversionToBaseUnit>
    </UnitOfMeasure>
  </UnitsDefinition>

  <WELL>
   <well_name>
    <pef:string>toodly #1</pef:string>
   </well_name>
   <distance_from_well>
     <pef:quantity uom="m">899</pef:quantity>
   </distance_from_well>
   <depth_of_well>
     <pef:real>12994</pef:real>
   </depth_of_well>
   <spud_date>
     <pef:date>
      <year>2000</year>
      <month>05</month>
      <day>12</day>
     </pef:date>
   </spud_date>
  </WELL>

<my:/RootElement>
Complex qualified
Case 1
<RootElement>

  <UnitsDefinition>
    <pef:UnitOfMeasure uid="m" acronym="m"/>
    <pef:UnitOfMeasure uid="ft1" acronym="ft US">US Survey Foot
      <pef:ConversionToBaseUnit baseUnit="m">
        <pef:numerator>12</pef:numerator>
        <pef:denominator>39.37</pef:denominator>
      </pef:ConversionToBaseUnit>
    </pef:UnitOfMeasure>
  </UnitsDefinition>

  <WELL>
   <well_name>
    <pef:string>toodly #1</pef:string>
   </well_name>
   <distance_from_well>
     <pef:quantity uom="m">899</pef:quantity>
   </distance_from_well>
   <depth_of_well>
     <pef:real>12994</pef:real>
   </depth_of_well>
   <spud_date>
     <pef:date>
      <pef:year>2000</pef:year>
      <pef:month>05</pef:month>
      <pef:day>12</pef:day>
     </pef:date>
   </spud_date>
  </WELL>

</RootElement>
Complex qualified
Case 2
<my:RootElement>

  <my:UnitsDefinition>
    <pef:UnitOfMeasure uid="m" acronym="m"/>
    <pef:UnitOfMeasure uid="ft1" acronym="ft US">US Survey Foot
      <pef:ConversionToBaseUnit baseUnit="m">
        <pef:numerator>12</pef:numerator>
        <pef:denominator>39.37</pef:denominator>
      </pef:ConversionToBaseUnit>
    </pef:UnitOfMeasure>
  </my:UnitsDefinition>

  <my:WELL>
   <my:well_name>
    <pef:string>toodly #1</pef:string>
   </my:well_name>
   <my:distance_from_well>
     <pef:quantity uom="m">899</pef:quantity>
   </my:distance_from_well>
   <my:depth_of_well>
     <pef:real>12994</pef:real>
   </my:depth_of_well>
   <my:spud_date>
     <pef:date>
      <pef:year>2000</pef:year>
      <pef:month>05</pef:month>
      <pef:day>12</pef:day>
     </pef:date>
   </my:spud_date>
  </my:WELL>

<my:/RootElement>

The Simple Cases have a single namespace. The qualified must have the same prefix in front of every tag. In this case the prefix is the blank. In the simple unqualified case, only the RootElement has the namespace qualifier. It must NOT be blank.

In the complex case, there are two namespaces. The pef prefix comes from the schemas namespace. The pr tag comes from the application schema that uses the POSC schemas as one part of it. In the unqualified case, there is again the pr prefix in front of the RootElement. But in addition, there is a pef prefix in front of the pef data type elements: string, quantity, real, and date. Note, though, that the children of date do NOT have prefixes (because things are unqualified).

In the complex, qualified, all tags have a namespace prefix. Not only do the string, quantity, real, and date tags have prefixes, but their children (year, month, day) also have prefixes. In case 1, the blank namespace is used for all the other tags, while in case 2 the pr prefix is used. This is just to show the various options.

One issue to resolve is whether people prefer the qualified or the unqualified versions. One of these must be chosen - and the other will be abandoned.

Simple Example, Unqualified

Consider a simple case, in which a single module is being imported into the application schema. In particular, assume that you want to import the units module to support quantities. Here is what the output XML would look like:
  ...some header cards...
  <UnitsDefinition>
    <UnitOfMeasure uid="m" acronym="m"/>
    <UnitOfMeasure uid="ft1" acronym="ft US">US Survey Foot
      <ConversionToBaseUnit baseUnit="m">
        <numerator>12</numerator>
        <denominator>39.37</denominator>
      </ConversionToBaseUnit>
    </UnitOfMeasure>
  </UnitsDefinition>

  <distanceFromWell uom="m">899</distanceFromWell>
  <depthOfWell uom="ft1">12994</depthOfWell>

The XML Schema will be quite simple. It will have an element, UnitsDefinition, of type unitBlock, a distanceFromWell element of type quant, and a depthOfWell tag also of type quant. The data types, unitBlock and quant, come from the unitsofmeasure.xml file in the POSC schemas area.

The XML Schema will import the file under the http://www.posc.org/schemas namespace, and will then be able to use the data types. Here is the schema:

<?xml version="1.0"?>
<schema
      targetNamespace="http://www.practice.org"
      elementFormDefault="unqualified"
      xmlns:test="http://www.practice.org"
      xmlns:posc="http://www.posc.org/schemas"
      xmlns="http://www.w3.org/2000/10/XMLSchema"
      xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance">

<import namespace="http://www.posc.org/schemas"
       schemaLocation="http://www.posc.org/schemas/units_u.xsd"/>

<element name="RootElement">
 <complexType>
  <sequence>
   <element name="UnitsDefinition" type="posc:unitBlock"/>
   <element name="distanceFromWell" type="posc:quant"/>
   <element name="depthOfWell" type="posc:quant"/>
  </sequence>
 </complexType>
</element>

</schema>

The schema card sets up a target namespace for this application schema: http://www.practice.org. It also sets up the namespace prefixes for the practice and the schemas namespaces. It also, of course, sets up the namespace for the XML Schema file located at www.w3.org. Note also that, for this example, the elements are given as unqualified. This means that only the global elements will need a namespace qualifier in the XML file.

The next card, the import, pulls in the file for the schemas namespace. Note that only one file can be pulled in for a given namespace.

Finally, the schema is developed, using the datatypes unitBlock and quant.

Assume these are saved in the file http://www.posc.org/practice/unitstest.xsd.

The XML

The XML from above is expanded to show the all-important RootElement tag.

<?xml version="1.0"?>
<my:RootElement 
       xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
       xmlns:my="http://www.practice.org"
       xsi:schemaLocation="http://www.practice.org
                  http://www.posc.org/practice/unitstest.xsd">

  <UnitsDefinition>
    <UnitOfMeasure uid="m" acronym="m"/>
    <UnitOfMeasure uid="ft1" acronym="ft US">US Survey Foot
      <ConversionToBaseUnit baseUnit="m">
        <numerator>12</numerator>
        <denominator>39.37</denominator>
      </ConversionToBaseUnit>
    </UnitOfMeasure>
  </UnitsDefinition>

  <distanceFromWell uom="m">899</distanceFromWell>
  <depthOfWell uom="ft1">12994</depthOfWell>

</my:RootElement>

The RootElement tag defines all the namespace information, and tells the XML reader where to find the schema.

  1. The http://www.practice.org namespace is given a prefix of pr.
  2. The schemas namespace is not mentioned. No global elements were brought in, so there are no elements from this namespace.
  3. The schema location we developed is given. The schemaLocation has two parts. The first is the namespace, and the second is the URI to locate the file.
  4. Since the practice namespace has a prefix of pr, all global elements defined in the schema must be prefixed with pr. The schema definition only created a single global element: RootElement. All other elements are local. So the RootElement tag is the only one with the prefix.

Comment: You may try to do away with the pr prefix by setting

       xmlns="http://www.practice.org"
I.e., by setting the practice namespace to have no prefix. This does not work. The XML interpreter will read all the other "unprefixed" tags as being in that namespace. It will give an error, since we have said that the elementFormDefault is unqualified, so the local elements should not have any namespace. It reads the blank namespace as "practice" rather than "blank".

Simple Example, Qualified

Here are the differences between the simple example, unqualified, and the simple example, qualified.

More Complex Example, Unqualified

In this example, two new complications will be added: (1) More than one module will be imported, and (2) Some global elements will be imported.

The scenario is that we wish to import the units module AND the pef data types. The pef data types define a bunch of global elements for the Epicentre data types, which will need a namespace prefix. (Note in passing that the pef data types, which are in the file, peftypes.xsd, will include other modules in the same schemas namespace. As long as everything is being done in the same directory, with the same target namespace, the include can be used to bring in as many files as needed.)

Here is the sample XML file:
<?xml version="1.0"?>
<my:RootElement 
       xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
       xmlns:my="http://www.practice.org"
       xmlns:pef="http://www.posc.org/schemas"
       xsi:schemaLocation="http://www.practice.org
                  http://www.posc.org/practice/pef.xsd">

  <UnitsDefinition>
    <UnitOfMeasure uid="m" acronym="m"/>
    <UnitOfMeasure uid="ft1" acronym="ft US">US Survey Foot
      <ConversionToBaseUnit baseUnit="m">
        <numerator>12</numerator>
        <denominator>39.37</denominator>
      </ConversionToBaseUnit>
    </UnitOfMeasure>
  </UnitsDefinition>

  <WELL>
   <well_name>
    <pef:string>toodly #1</pef:string>
   </well_name>
   <distance_from_well>
     <pef:quantity uom="m">899</pef:quantity>
   </distance_from_well>
   <depth_of_well>
     <pef:real>12994</pef:real>
   </depth_of_well>
   <spud_date>
     <pef:date>
      <year>2000</year>
      <month>05</month>
      <day>12</day>
     </pef:date>
   </spud_date>
  </WELL>

<my:/RootElement>

Note that the global tags from peftypes.xsd (string, quantity, real, and date) are all prefixed with pef:, which is the namespace prefix for the schemas namespace.

The application schema, which is stored in pef.xsd, will need to import two files, and assign them to the schemas namespace. This is not possible. Only a single file can be imported for a namespace. However, there is a way around this dilemma.

A schema can "include" more than one file, as long as the included files are in the same target namespace, and they are targeted also to the same target namespace. I cannot "include" them into the pef.xsd file, because pef.xsd has the practice target namespace. What I CAN do is to include all the files in a single file, and then import this "grouping" file into pef.xsd. Here is the intermediate file, which will be stored in URI http://www.posc.org/practice/group.xsd
  <?xml version="1.0"?>
  <schema
     targetNamespace="http://www.posc.org/schemas"
     xmlns="http://www.w3.org/2000/10/XMLSchema"
     >

  <include schemaLocation="http://www.posc.org/schemas/units_u.xsd"/>
  <include schemaLocation="http://www.posc.org/schemas/peftypes_u.xsd"/>

  </schema>
Note the following:

  1. The target namespace is the same as the target namespaces of the included files.
  2. The files are included, not imported. Thus, I can get many of them.
This mechanism allows me to "import" more than one module from the same namespace.

Here is the pef.xsd file that imports this group.xsd file.
<?xml version="1.0"?>
<schema
      targetNamespace="http://www.practice.org"
      elementFormDefault="unqualified"
      xmlns:test="http://www.practice.org"
      xmlns:posc="http://www.posc.org/schemas"
      xmlns="http://www.w3.org/2000/10/XMLSchema"
      xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance">

<import namespace="http://www.posc.org/schemas"
       schemaLocation="http://www.posc.org/practice/local.xsd"/>

<element name="RootElement">
 <complexType>
  <sequence>
   <element name="UnitsDefinition" type="posc:unitBlock"/>
   <element name="WELL" type="test:wellType"/>
  </sequence>
 </complexType>
</element>

<complexType name="wellType">
 <sequence>
  <element name="well_name">
   <complexType>
    <sequence>
     <element ref="posc:string"/>
    </sequence>
   </complexType>
  </element>
  <element name="distance_from_well">
   <complexType>
    <sequence>
     <element ref="posc:quantity"/>
    </sequence>
   </complexType>
  </element>
  <element name="depth_of_well">
   <complexType>
    <sequence>
     <element ref="posc:real"/>
    </sequence>
   </complexType>
  </element>
  <element name="spud_date" minOccurs="0">
   <complexType>
    <sequence>
     <element ref="posc:date"/>
    </sequence>
   </complexType>
  </element>
 </sequence>
</complexType>

</schema>

Although this seems like a complex schema, it is really quite simple. It defines a root tag, RootElement, with two child tags, UnitsDefinition and WELL. The UnitsDefinition is as before, and the WELL tag has child tags of well_name, distance_from_well, depth_of_well, and spud_date. These tags, in turn, use the elements from the peftypes, string, quantity, real, and date. This is very much like the mapping of a simple data model into an XML file as defined in the PEF XML document.

Note that the only global element in this schema is RootElement. Hence, the XML file above only uses the pr prefix for the RootElement tag. However, the peftypes.xsd defines many global elements. There is one for each data type: string, real, quantity, and date, in this example. Thus, each of these tags must be prefixed with the schemas namespace prefix (which is pef). Finally, it should be noted that the children of date, even though they come from the schemas namespace, are not prefixed because they are not global AND because the peftypes.xsd specifies that the elementFormDefault is unqualified.


Last Modified: February 1, 2001
© Copyright 2000 POSC. All rights reserved.