OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

 


 

   Re: XML Schemas: Best Practices

[ Lists Home | Date Index | Thread Index ]
  • From: "Roger L. Costello" <costello@mitre.org>
  • To: xml-dev@lists.xml.org
  • Date: Mon, 30 Oct 2000 16:21:15 -0500

Hi Folks,

I would like to move our discussions to the next topic on the Best
Practices list [1].

Issue:

In a project where multiple schemas are created, should each schema
reside in a separate namespace, or should all the schemas reside within
a single, umbrella namespace, or should some of the schemas be in no
namespace?

Introduction

In a typical project many schemas will be created. The schema designer
is then confronted with this issue: "shall I define one namespace for
all the schemas, or shall I create a different namespace for each
schema, or shall I have some of the schemas be in no namespace?" 

What are the tradeoffs in creating multiple namespaces versus a single
namespace versus a mixture of namespaces and no namespaces? 

What guidance would you give someone starting on a project that will
create multiple schemas?  Which design approach should the person use: 

     [1] Multiple Namespaces Design (Heterogeneous Name-Space): 
         create a different namespace for each schema
            (if so, how should the namespaces be related?)  
     [2] Single, Umbrella Namespace Design (Homogeneous Name-Space):
         create one umbrella namespace for all schemas
     [3] Mixed Namespace/No-Namespace Design: 
         create a namespace for the "main" schema and no namespace 
         for the "supporting" schemas (we will see the "chameleon"
         capability this design approach provides)

To judge the merits of the three design approaches it will be useful to
take an example and see each approach "in action".

Example: XML Data Model of a Company

Suppose that your project involves creating a model of a company using
XML Schemas. One very simple model is to divide the company
functionality up along these lines:

Company Schema
   Person schema
   Product schema

"A company is comprised of people and products."

Let's create the company, person, and product schemas using the three
design approaches.

[1] The first design approach says to create a namespace for each
schema.  What follows are the three schemas.  Note that each schema
creates a new targetNamespace.

Product.xsd (multiple namespaces version)

<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2000/10/XMLSchema"
        targetNamespace="http://www.product.org"
        elementFormDefault="unqualified"
        xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
        xsi:schemaLocation=
                      "http://www.w3.org/2000/10/XMLSchema
                       http://www.w3.org/2000/10/XMLSchema.xsd">
    <complexType name="Product">
        <sequence>
           <element name="Type" type="string" 
                    minOccurs="1" maxOccurs="1"/>
        </sequence>
    </complexType>
</schema>

Person.xsd (multiple namespaces version)

<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2000/10/XMLSchema"
        targetNamespace="http://www.person.org"
        elementFormDefault="unqualified"
        xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
        xsi:schemaLocation=
                      "http://www.w3.org/2000/10/XMLSchema
                       http://www.w3.org/2000/10/XMLSchema.xsd">
    <complexType name="Person">
        <sequence>
           <element name="Name" type="string" 
                    minOccurs="1" maxOccurs="1"/>
           <element name="SSN" type="string" 
                    minOccurs="1" maxOccurs="1"/>
        </sequence>
    </complexType>
</schema>

Company.xsd (multiple namespaces version)

<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2000/10/XMLSchema"
        targetNamespace="http://www.company.org"
        elementFormDefault="unqualified"
        xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
        xsi:schemaLocation=
                      "http://www.w3.org/2000/10/XMLSchema
                       http://www.w3.org/2000/10/XMLSchema.xsd"
        xmlns:per="http://www.person.org"
        xmlns:pro="http://www.product.org">
    <import namespace="http://www.person.org"
            schemaLocation="Person.xsd"/>
    <import namespace="http://www.product.org"
            schemaLocation="Product.xsd"/>
    <element name="Company">
        <complexType>
            <sequence>
                <element name="Person" type="per:Person" 
                         minOccurs="1" maxOccurs="unbounded"/>
                <element name="Product" type="pro:Product" 
                         minOccurs="1" maxOccurs="unbounded"/>
            </sequence>
        </complexType>
    </element>
</schema>

Note the three namespaces that were created by the three schemas:

   http://www.product.org
   http://www.person.org
   http://www.company.org

[2] The second design approach says to create a single, umbrella
namespace.  What follows are the three schemas.  Note that all schemas
have the same targetNamespace.

Product.xsd (single, umbrella namespace version)

<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2000/10/XMLSchema"
        targetNamespace="http://www.company.org"
        elementFormDefault="unqualified"
        xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
        xsi:schemaLocation=
                      "http://www.w3.org/2000/10/XMLSchema
                       http://www.w3.org/2000/10/XMLSchema.xsd">
    <complexType name="Product">
        <sequence>
           <element name="Type" type="string" 
                    minOccurs="1" maxOccurs="1"/>
        </sequence>
    </complexType>
</schema>

Person.xsd (single, umbrella namespace version)

<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2000/10/XMLSchema"
        targetNamespace="http://www.company.org"
        elementFormDefault="unqualified"
        xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
        xsi:schemaLocation=
                      "http://www.w3.org/2000/10/XMLSchema
                       http://www.w3.org/2000/10/XMLSchema.xsd">
    <complexType name="Person">
        <sequence>
           <element name="Name" type="string" 
                    minOccurs="1" maxOccurs="1"/>
           <element name="SSN" type="string" 
                    minOccurs="1" maxOccurs="1"/>
        </sequence>
    </complexType>
</schema>

Company.xsd (single, umbrella namespace version)

<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2000/10/XMLSchema"
        targetNamespace="http://www.company.org"
        elementFormDefault="unqualified"
        xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
        xsi:schemaLocation=
                      "http://www.w3.org/2000/10/XMLSchema
                       http://www.w3.org/2000/10/XMLSchema.xsd"
        xmlns:c="http://www.company.org">
    <include schemaLocation="Person.xsd"/>
    <include schemaLocation="Product.xsd"/>
    <element name="Company">
        <complexType>
            <sequence>
                <element name="Person" type="c:Person" 
                         minOccurs="1" maxOccurs="unbounded"/>
                <element name="Product" type="c:Product" 
                         minOccurs="1" maxOccurs="unbounded"/>
            </sequence>
        </complexType>
    </element>
</schema>

Note the single namespace for all three schemas:

   http://www.company.org

Also note the mechanism use for reusing components from other schemas -
include.  When reusing components from a schema with a different
namespace the <import> element is used.  When reusing components from a
schema with the same namespace the <include> element is used.

[3] The third design approach says to create a targetNamespace for the
"main" schema and no targetNamespace for all the "supporting" schemas.  
What follows are the three schemas.  Note that the company schema (the
"main" schema) has a targetNamespace and the person and product schemas
(the "supporting" schemas) have no targetNamespace:

Product.xsd (no targetNamespace)

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
        elementFormDefault="unqualified"
        xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
        xsi:schemaLocation=
                      "http://www.w3.org/2000/10/XMLSchema
                       http://www.w3.org/2000/10/XMLSchema.xsd">
    <xsd:complexType name="Product">
        <xsd:sequence>
           <xsd:element name="Type" type="xsd:string" 
                        minOccurs="1" maxOccurs="1"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

Person.xsd (no targetNamespace)

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
        elementFormDefault="unqualified"
        xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
        xsi:schemaLocation=
                      "http://www.w3.org/2000/10/XMLSchema
                       http://www.w3.org/2000/10/XMLSchema.xsd">
    <xsd:complexType name="Person">
        <xsd:sequence>
           <xsd:element name="Name" type="xsd:string" 
                        minOccurs="1" maxOccurs="1"/>
           <xsd:element name="SSN" type="xsd:string" 
                        minOccurs="1" maxOccurs="1"/>
        </xsd:sequence>
    </xsd:complexType>
</xsd:schema>

Company.xsd (main schema, reuses the no-targetNamespace-schemas)

<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2000/10/XMLSchema"
        targetNamespace="http://www.company.org"
        elementFormDefault="unqualified"
        xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
        xsi:schemaLocation=
                      "http://www.w3.org/2000/10/XMLSchema
                       http://www.w3.org/2000/10/XMLSchema.xsd"
        xmlns:c="http://www.company.org">
    <include schemaLocation="Person.xsd"/>
    <include schemaLocation="Product.xsd"/>
    <element name="Company">
        <complexType>
            <sequence>
                <element name="Person" type="c:Person" 
                         minOccurs="1" maxOccurs="unbounded"/>
                <element name="Product" type="c:Product" 
                         minOccurs="1" maxOccurs="unbounded"/>
            </sequence>
        </complexType>
    </element>
</schema>

First, note that a schema is able to reuse components from schemas that
have no targetNamespace, using <include>.  In this example, the company
schema has reused the components in Product.xsd and Person.xsd (even
though they have no targetNamespace).

Second, a very interesting characteristic of a schema with a namespace
that <include>s schemas with no targetNamespace is:
   - The components in the schemas with no targetNamespace 
     get namespace-coerced.  That is, the components "take on"
     the namespace of the schema that is doing the <include>
        For example, the Product complexType in Products.xsd
        gets implicitly coerced into the company namespace.
        That explains the reason for the namespace qualifier 
        in type="c:Product" above.  Same for the Person
        complexType in Person.xsd.

"Chameleon effect" ...  This is a term coined by Henry Thompson to
describe the ability of components in a schema with no targetNamespace
to readily take on the namespace of other schemas.  This is very
powerful!

Let's turn now to the instance document.  How does an instance
document differ for each of the above schemas?  All of the above
schemas have been designed to hide (localize) the namespace
complexity within the schemas (as provided by
elementFormDefault="unqualified").  Hence, the instance documents all
have the same form:

<?xml version="1.0"?>
<c:Company xmlns:c="http://www.company.org"
           xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
           xsi:schemaLocation=
                          "http://www.company.org
                           Company.xsd">
        <Person>
                <Name>John Doe</Name>
                <SSN>123-45-6789</SSN>
        </Person>
        <Product>
                <Type>Widget</Type>
        </Product>
</c:Company>

It is when the schemas expose their namespaces in instance documents
that the differences appear.  Suppose that in the above schemas,
instead of elementFormDefault="unqualified", they all said 
elementFormDefault="qualified".  Now let's see what the instance
documents would look like for each design approach:

[1] Company.xml (conforming to multiple namespaces version)

<?xml version="1.0"?>
<c:Company xmlns:c="http://www.company.org"
           xmlns:pro="http://www.product.org"
           xmlns:per="http://www.person.org"
           xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
           xsi:schemaLocation=
                          "http://www.company.org
                           Company.xsd
                           http://www.product.org
                           Product.xsd
                           http://www.person.org
                           Person.xsd">
        <c:Person>
                <per:Name>John Doe</per:Name>
                <per:SSN>123-45-6789</per:SSN>
        </c:Person>
        <c:Product>
                <pro:Type>Widget</pro:Type>
        </c:Product>
</c:Company>

Note that:
   - there needs to be a namespace declaration for each namespace
   - schemaLocation must list all the different 
     namespace/schema-doc pairs
   - the elements must all be uniquely qualified.

[2] Company.xml (conforming to single, umbrella namespace version)

<?xml version="1.0"?>
<Company xmlns="http://www.company.org"
         xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
         xsi:schemaLocation=
                         "http://www.company.org
                          Company.xsd">
        <Person>
                <Name>John Doe</Name>
                <SSN>123-45-6789</SSN>
        </Person>
        <Product>
                <Type>Widget</Type>
        </Product>
</Company>

Since all the schemas are in the same namespace the instance document is
able to take advantage of that by using a default namespace.

[3] Company.xml (conforming to main namespace with supporting
no-namespace version)

<?xml version="1.0"?>
<Company xmlns="http://www.company.org"
         xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
         xsi:schemaLocation=
                        "http://www.company.org
                         Company.xsd">
        <Person>
                <Name>John Doe</Name>
                <SSN>123-45-6789</SSN>
        </Person>
        <Product>
                <Type>Widget</Type>
        </Product>
</Company>

Both of the schemas that have no targetNamespace take on the the company
namespace (the Chameleon effect).  Thus, all components are in the same
namespace and the instance document takes advantage of this by declaring
a default namespace.

Discussion

(a) Is the above representative of the various design approaches
    that can be taken with regards to the use of namespaces in a
    multi-schema project?  

(b) I think that it would be useful to give a name to the three
    design approaches demonstrated above.  What name would you 
    give to:

     [1] The multiple namespaces design approach
     [2] The single, umbrella namespace design approach
     [3] The mixed namespace/no-namespace design approach

(c) If someone were to ask you, "My project has created 
    multiple schemas. What should I do about namespaces?  
    Should the schemas be put in namespaces or not?  Should 
    there be a homogenous name space, or a heterogeneous 
    name space?"  How would you answer that person?

Thanks!  /Roger

[1] http://www.xfront.com/BestPractices.html





 

News | XML in Industry | Calendar | XML Registry
Marketplace | Resources | MyXML.org | Sponsors | Privacy Statement

Copyright 2001 XML.org. This site is hosted by OASIS