<article xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation='file:///Users/jbarnum/source/DescriptorHTML5Web/WebContent/articles/xsl/article.xsd'>

  <title>XML Schema and Namespaces</title>       
  <short-title>Schema and Namespaces</short-title>
  <creation-date>2011-05-11</creation-date>
  <version>1.0</version>
  <author>Joel Barnum</author> 
  <organization>Descriptor Systems</organization>
  <description>
      Namespaces in XML are a way to organize names (e.g. element names) so as 
      to avoid name conflicts. XML Schema lets you define the rules for 
      XML content so that a given XML document is correct for your application. This
      article discusses how the two concepts interact.
  </description>
  <prereqs>
    <ul>
      <li>
        How to write simple XML schemas.
      </li>
      <li>
        The basics of how namespaces in XML work.
      </li>
    </ul>
  </prereqs>
  <keywords>XML namespace schema elementFormDefault targetNamespace</keywords>
  <body>
    <h2>Namespaces Review</h2>
    <p>
      Namespaces in XML provide two basic functions:
      <ol> 
        <li>
          They allow you to disambiguate XML element names, so that you can
          intermingle XML from different vocabularies that happen to use
          the same names.
        </li>
        <li>
          They allow you to identify element and attribute names according
          to their namespace. In other words, given a name, the reader can
          see that the name belongs to a collection of other names.
        </li>
      </ol>
    </p>
    <p>
      To use namespaces, you create <b>qualified names</b> that often
      use a <b>prefix</b> to identify the namespace. Then you map the
      prefix to a globally unique string, such as a URL (which can be unique
      because domain names are unique). Thus, a prefix-qualified name consists
      of a prefix and a <b>local name</b>, as shown in Figure 1.
    </p>
    <image href="namespace.jpg" title="Figure 1: Qualified Names">
      <width>708</width>
      <height>201</height>
    </image>   
    <p>
      To map or assign a prefix to a namespace URL, you use the <b>xmlns</b> attribute
      as shown in Listing 1:
    </p>
    <codelisting><![CDATA[<hr:employee xmlns:hr="http://goliath.com/hr">
      <hr:name>Paul Westerberg</hr:name>
      <hr:address>123 Elm Street</hr:address>
<hr:employee>]]></codelisting>
    <caption>Listing 1: Mapping a Namespace Prefix</caption>
    <p>
      The XML Namespaces specification also allows for a <b>default namespace</b>
      which lets you avoid using a prefix while still qualifying names, at the
      expense of human readability (it makes it more difficult for human readers
      to determine if a given element is a namespace or not). To use a default namespace, you use the
      <b>xmlns</b> attribute without a prefix. Listing 2 shows an example of using a default
      namespace:
    </p>
    <codelisting><![CDATA[<employee xmlns="http://goliath.com/hr">
      <name>Paul Westerber</name>
      <address>123 Elm Streen</address>
</employee>]]></codelisting>
    <caption>Listing 2: Using a Default Namespace</caption>
    <h2>Schema Namespaces</h2>
    <p>
      Schema itself defines and uses three namespaces, with the following
      URIs:
      <ul>
        <li>
          http://www.w3.org/XMLSchema-datatypes
        </li>
        <li>
          http://www.w3.org/XMLSchema-instance
        </li>
        <li>
          http://www.w3.org/XMLSchema
        </li>
      </ul>      
    </p>
    <p>
      The first namespace URI, for <b>datatypes</b>, separates out the part of Schema
      used to define XML data types, such as <b>integer</b>, <b>decimal</b> and <b>string</b>.
      This separate namespace exists primarily to support non-Schema technologies (e.g.
      <a href="http://relaxng.org/">RelaxNG</a>) that use the Schema types without using the rest of Schema.
    </p>
    <p>
      The second namespace URI, for <b>instances</b>, lets XML documents reference 
      schemas. We will see examples of it later in this article.
    </p>
    <p>
      The third namespace URI, for Schema itself, defines the XML vocabulary so
      for schemas, e.g. <b>minOccurs</b>. Note that this namespace "includes"
      the datatypes namespace so that when you write a schema, you don't need to
      define the datatypes namespace separately.
    </p>
    <p>
      When you use these namespace URIs, you can map them to any prefix, but it's
      traditional to use <b>xsi</b> for the <b>instances</b> namespace.
    </p>
    <h2>Referencing a Schema from an Instance Document</h2>
    <p>
      Now let's see how we can use the <b>instances</b> namespace so that
      an XML document (the instance) can reference one or more schemas. Once we
      do that, then we can parse the instance and the parser will fetch the
      schema and use it to validate the instance. There are two syntaxes to
      reference a schema, depending on whether the instance document itself
      uses namespaces as shown in Figure 2.
    </p>
    <image href="reference-schema.png" title="Figure 2: Referencing a Schema from an Instance">
      <width>723</width>
      <height>271</height>
    </image>
    <p>
      As shown in Figure 2, if the instance document has no elements or attributes
      in an application-defined namespace, it uses <b>xsi:noNamespaceSchemaLocation</b>
      to reference its schema. Note that the reference is itself a URL - Figure 2 uses
      a relative "file" URL, but it could be a remote URL, perhaps using HTTP.
    </p>
    <p>
      But if the instance document itself has elements or attributes in a namespace,
      the instance uses <b>xsi:schemaLocation</b> to reference one or more schemas,
      each of which validates content from a single namespace. So that makes the
      syntax of the <b>xsi:schemaLocation</b> attribute more complex; it needs to specify
      at least TWO things: the namespace URI that the schema validates, and the location of
      the schema. As shown in Figure 2, for an instance document that uses a single
      namespace, the value of the <b>xsi:schemaLocation</b> attribute contains two
      substrings, separated by whitespace. <b>http://myURI</b> is the first substring
      and <b>schema2.xsd</b> is the second. We discuss this syntax in more detail
      next.
    </p>
    <h2>The Syntax of the xsi:schemaLocation Attribute</h2>
    <p>
      The <b>xsi:schemaLocation</b> attribute's value consists of one or more pairs
      of substrings, the first of which identifies an namespace URI, while the second
      references a schema. The substrings, and each pair themselves, must be separated
      by whitespace, which includes spaces, tabs and new line characters. Figure 3
      shows the general syntax:
    </p>
    <image href="schemalocation.png" title="Figure 3: xsi:schemaLocation Attribute Value Syntax">
      <width>720</width>
      <height>104</height>
    </image>
    <p>
      If you have an instance document that uses many namespaces, the <b>xsi:schemaLocation</b>
      attribute's value can get quite complex. For example, this listing shows
      an XML file from an application that uses the <a href="http://www.springsource.org/">Spring Framework</a>:
    </p>
    <codelisting><![CDATA[<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" 
	xmlns:jms="http://www.springframework.org/schema/jms"
	xmlns:lang="http://www.springframework.org/schema/lang" 
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation=
  "http://www.springframework.org/schema/aop 
   http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
   http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
   http://www.springframework.org/schema/context 
   http://www.springframework.org/schema/context/spring-context-2.5.xsd
   http://www.springframework.org/schema/jee 
   http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
   http://www.springframework.org/schema/lang 
   http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
   http://www.springframework.org/schema/tx 
   http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
   http://www.springframework.org/schema/util 
   http://www.springframework.org/schema/util/spring-util-2.5.xsd">
        
        . . .
        
</beans>]]></codelisting>
    <caption>Listing 3: An Instance Document that References Multiple Schemas</caption>
    <p>
      In the above code listing, note how the <b>xsi:schemaLocation</b> attribute's
      value consists of seven pairs of substrings, separated by new-line characters.
      The first of each pair (e.g. <b>http://www.springframework.org/schema/aop</b>
      is a namespace URI, while the second (e.g. <b>http://www.springframework.org/schema/aop/spring-aop-2.5.xsd</b>
      is the actual location of an XML schema file. Note how the latter of the pair
      ends in the conventional file extension for Schema, <b>.xsd</b>.
    </p>
    <p>
      When you validate a document like the one above, the parser fetches each of the schemas (.xsd files),
      ensures that each actually validates the namespace specified, and then uses the schemas to
      validate the document.
    </p>
    <h2>The targetNamespace Attribute</h2>
    <p>
      A given schema can only validate a single namespace. This bears repeating: A given schema validates
      a single namespace. In fact, you could derive this concept by looking closely at the <b>schemaLocation</b>
      attribute in Listing 1: each schema reference requires both a namespace URI and the location of
      the schema file. So it follows that if a given instance document uses multiple namespaces, it must
      reference multiple schemas.
    </p>
    <p>
      So when you write a schema that validates XML that's in a namespace, you must indicate which
      namespace the schema validates. You do so by writing a <b>targetNamespace</b> attribute
      on the <i>schema</i> root element as shown in Listing 3:
    </p>
    <codelisting><![CDATA[<xs:schema 
  targetNamespace="http://goliath.com/ABCD" 
  xmlns="http://goliath.com/ABCD"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">

. . .

</xs:schema>]]></codelisting>
    <caption>Listing 4: The targetNamespace Attribute</caption>
    <p>
      In Listing 4, we also specify the target namespace as the default namespace
      in the schema - that's not required, but is a common way to write schemas.
    </p>
    <h2>Global and Local Elements in a Schema</h2>
    <p>
      When you write a schema, you <i>declare</i> the elements and attributes
      that will appear in an instance document. You can write those declarations
      at either <b>global</b> or <b>local</b> scope in the schema, and it turns
      out that this choice has a significant side effect on how the instance document
      uses namespaces.
    </p>
    <p>
      <b>Globally</b> defined element and attribute declarations live at so-called
      <b>root</b> level in the schema - that is, their parent is the <b>schema</b>
      root element itself. <b>Locally</b> defined declarations are nested within
      other declarations as shown in Figure 4. 
    </p>
    <image href="global-and-local.jpg" title="Figure 4: Global and Local Declarations in a Schema">
      <width>700</width>
      <height>337</height>
    </image>
    <p>
      The primary benefit, or rationale, for declaring globally is that you can
      reference globally declared elements and attributes elsewhere in the schema.
      In other words, globally declared elements and attributes are a form of
      re-use that let you factor-out commonly used declarations and re-use them
      as needed, thus reducing redundancy in the schema. So for example, in Figure 4, if some
      other declaration in the schema needed to use <b>firstname</b> it could not
      do so since that declaration is not at global scope.
    </p>
    <h2>Global vs Local Element and Attribute Declarations</h2>
    <p>
      As mentioned earlier, whether an element or attribute is declared globally or locally
      in the schema has a significant side-effect on how an instance document
      uses namespaces. We can summarize how it works with two straightforward rules:
    </p>
    <ul>
      <li>
        <b>RULE 1: </b>Elements and attributes declared at global scope in a schema MUST be
        namespace qualified in an instance document.
      </li>
      <li>
        <b>RULE 2: </b>By default, elements and attributes declared at local scope in
        a schema MUST NOT be namespace qualified in an instance document.
      </li>
    </ul>
    <p>
      For <b>Rule 1</b>, by "namespace qualified", we mean that the globally declared
      element must be in a namespace in an instance document, either with a prefix
      or a default namespace.
    </p>
    <p>
      For <b>Rule 2</b>, we can override this default, as we will see in a moment.
    </p>
    <p>
      The upshot of these two rules is that the schema author has complete control
      over how namespaces are used in an instance document. Let's look at an
      example.
    </p>
    <h2>Namespace and Schema Example, Number One</h2>
    <p>
      Let's start by looking at a schema that has some elements declared
      globally, and some locally.
    </p>
    <codelisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
  targetNamespace="http://goliath.com/ABCD" 
    xmlns="http://goliath.com/ABCD"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="student-name" type="xs:string" />

    <xs:element name="student">
      <xs:complexType>
        <xs:sequence>
          <xs:element ref="student-name" />
          <xs:element name="student-id" type="xs:positiveInteger" />
          <xs:element name="gpa" type="xs:decimal" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>

</xs:schema>]]></codelisting>
   <caption>Listing 5: Schemas and Namespaces Example #1, namespaces1.xsd</caption>
   <p>
     In Listing 5, note that the elements <b>student</b> and <b>student-name</b>
     are declared globally, while <b>student-id</b> and <b>gpa</b> are
     local declarations. By applying Rules 1 and 2, we can predict that in an
     instance document:
   </p>
     <ul>
       <li>
         <b>student-name</b> and <b>student</b> must be namespace-qualified due
         to Rule 1.         
       </li>
       <li>
         <b>student-id</b> and <b>gpa</b> must NOT be namespace-qualified due
         to Rule 2 (we have not overridden any defaults).
       </li>
     </ul>
     <p>
       Listing 6 shows an instance document that follows these rules:
     </p>
     <codelisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<p:student     
    xmlns:p="http://goliath.com/ABCD"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://goliath.com/ABCD namespaces1.xsd ">
    
    <p:student-name>Sam</p:student-name>
    <student-id>12</student-id>
    <gpa>3.44</gpa>
</p:student>
]]></codelisting>
   <caption>Listing 6: An Instance Document for Example #1, namespaces1.xml</caption>
   <p>
     In Listing 6, we defined a prefix <b>p</b> for the target namespace
     of the schema in Listing 5. Then, applying Rule 1, we explicitly
     prefix <b>student</b> and <b>student-name</b> since they are declared
     globally in the schema. Applying Rule 2, <b>student-id</b> and
     <b>gpa</b> have no prefix, and thus are not namespace-qualified (there
     is no <i>default</i> namespace in this instance document).
   </p>
   <p>
     If we had violated either of those rules, then the instance document
     would not be valid, and if we parsed it, the parser would complain.
   </p>
   <h2>Overriding the Default for Rule 2</h2>
   <p>
     Rule 2 states:
   </p>
    <ul>
      <li>
        <b>RULE 2: </b>By default, elements and attributes declared at local scope in
        a schema MUST NOT be namespace qualified in an instance document.
      </li>
    </ul>
    <p>
      The implication here is that we can override Rule 2 (we can never change
      how Rule 1 works: globally-declared elements and attributes MUST ALWAYS
      be namespace-qualified). Before we see how, let's talk about why. 
    </p>
    <p>
      Using the default Rule 2 makes it easier for XML authors - only the
      globally-declared elements and attributes have to be qualified. And that
      often solves the basic problem that namespaces address:  
      many times, name collisions only occur on top-level elements in an instance document.
      But occasionally, nested elements might be ambiguous and thus need 
      namespace qualification. If that's the case, we can override Rule 2.
    </p>
    <h2>The form Attribute</h2>
    <p>
      Schema provides two different ways to override Rule 2.
      The first way to override Rule 2 is to the <b>form</b> attribute.
      On any locally-declared element or attribute, in a schema, you can use the <b>form</b>
      attribute to force qualification in an instance document as shown in Listing 7:
    </p>
    <codelisting><![CDATA[<xs:schema . . .>

    <xs:element name="student">
      . . .
       <!-- locally defined element -->
       <xs:element form="qualified" name="gpa" type="xs:decimal" />
      . . .
    </xs:element>

</xs:schema>]]></codelisting>
   <caption>Listing 7: The form Attribute</caption>
   <p>
     So in Listing 7, we have decided that <b>gpa</b> element must always be 
     namespace-qualified in an instance document, even though it's declared locally
     in the schema.
   </p>
   <p>
     If you have many such locally-declared elements or attributes, it can get
     tedious writing individual <b>form</b> attributes. To address that, schema
     provides the <b>elementFormDefault</b> and <b>attributeFormDefault</b>
     attributes.
   </p>
   <h2>The elementFormDefault and attributeFormDefault Attributes</h2>
   <p>
     On the <b>schema</b> root element, you can establish a new default for
     locally-declared elements and attributes in a schema. The default for
     both of these (that is, if you don't specify them at all) is <b>unqualified</b>,
     thus leading to the Rule 2 we've already discussed. But as Listing 8 demonstrates,
     you can explicitly specify <b>elementFormDefault</b> or <b>attributeFormDefault</b>
     or both:
   </p>
   <codelisting><![CDATA[<xs:schema elementFormDefault="qualified" ...>

   <xs:element name="student">
     . . .
     <!-- locally defined element -->
     <xs:element name="gpa" type="xs:decimal" />
     . . .
   </xs:element>

</xs:schema>]]></codelisting>
  <caption>Listing 8: The elementFormDefault Attribute</caption>
  <p>
    So we can predict that in an instance document, the <b>gpa</b> element
    will need to be namespace-qualified. In fact, ALL locally declared elements
    in this schema will need to be namespace-qualified. 
  </p>
  <p>
    Note you can combine the approaches, that is specify <b>elementFormDefault</b>
    and/or <b>attributeFormDefault</b>
    on the schema root, AND specify <b>form</b> on an individual element or attribute's
    declaration. In case of a conflict,
    the <b>form</b> attribute takes precedence. This gives the
    schema author complete control over how namespaces are used in an
    instance document. Listing 9 shows
    a schema that demonstrates:
  </p>
  <codelisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://goliath.com/ABCD" 
    xmlns="http://goliath.com/ABCD"
    elementFormDefault="qualified"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="student-name" type="xs:string" />

    <xs:element name="student">
      <xs:complexType>
        <xs:sequence>
          <xs:element ref="student-name" />
          <xs:element name="student-id" type="xs:positiveInteger" />
          <xs:element form="unqualified" name="gpa" type="xs:decimal" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>

</xs:schema>]]></codelisting>
  <caption>Listing 9: Example #2: Using the elementFormDefault and form Attributes, namespaces3.xsd</caption>
  <p>
    Looking at Listing 9, we see that the schema's root element specifies
    <b>elementFormDefault</b> of <b>qualified</b> and that the declaration
    for the <b>gpa</b> element specifies <b>form</b> of <b>unqualified</b>.    
    Based on that,
    we can predict that in an instance document, the
    <b>student</b>, <b>student-name</b> and <b>student-id</b> elements will
    need namespace qualification, while <b>gpa</b> will not. Listing
    10 demonstrates such an instance document:
  </p>
  <codelisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<p:student     
    xmlns:p="http://goliath.com/ABCD" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://goliath.com/ABCD namespaces3.xsd ">
    
    <p:student-name>Sam</p:student-name>
    <p:student-id>12</p:student-id>
    <gpa>3.44</gpa>
</p:student>
]]></codelisting>
  <caption>Listing 10: An Instance Document for Schema Example #2, namespaces3.xml</caption>
  <h2>Summary</h2>
  <p>
    In this article, you've learned how schemas that validate XML content
    that use namespaces work, and how to control whether or not locally-declared
    elements and attributes are namespace-qualified in instance documents.
  </p>
  <p>
    If you found this article helpful, and want to learn more, we recommend
    that you go to the <a href="http://www.descriptor.com">Descriptor Systems</a>
    Web site and see how you can obtain training on this or other topics.
  </p>
  </body> 
</article>
