Chapter 3. Namespaces

Understanding namespaces is essential to understanding XML Schema. This chapter introduces namespaces and explains their relationship to schemas.

3.1. Namespaces in XML

Before we delve into the use of namespaces in schema documents, let’s take a minute to learn about namespaces in general. Namespaces are a surprisingly simple concept considering how much confusion and controversy it causes. The purpose of namespaces is to provide containers for the names used in XML. A name, such as table, can have several meanings. Its meaning in XHTML is very different from its meaning in a hypothetical language for describing office furniture, FurnitureML. An element or attribute name in an instance can be declared to be in a namespace, which provides context and identifies the XML vocabulary to which the element or attribute belongs.

image

Namespaces are defined by a separate W3C recommendation called Namespaces in XML, which is in two versions: 1.0 and 1.1. XML Schema 1.0 uses Namespaces 1.0, and XML Schema 1.1 uses Namespaces 1.1. There are few substantive differences between them, mentioned in the appropriate sections of this chapter.

image

3.1.1. Namespace names

Namespace names are Uniform Resource Identifiers (URIs). URIs encompass URLs of various schemes (e.g., HTTP, FTP, gopher, telnet), as well as URNs (Uniform Resource Names). Many namespaces are written in the form of HTTP URLs, such as http://datypic.com/prod. It is also legal to use a URN, such as urn:example:org.

The main purpose of a namespace is not to point to a location where a resource resides. Instead, much like a Java package name, it is intended to provide a unique name that can be associated with a particular person or organization. Therefore, namespace names are not required to be dereferenceable. That is, there does not necessarily need to be an HTML page or other resource that can be accessed at http://datypic.com/prod. The namespace URI could point to a schema, an HTML page, a directory of resources, or nothing at all. This is explained further in Section 21.8.5 on p. 589.

Namespace names are case-sensitive. Two namespaces are considered different if their capitalization is different, even if you might consider them equivalent URLs. For example, http://DATYPIC.COM/prod and http://datypic.com/prod represent different namespaces, because they are capitalized differently.

image

Although relative URI references, such as ../prod or just plain prod are legal as URIs, they are not appropriate namespace names. A namespace name should be unique, and it is difficult to ensure the uniqueness of ../prod. In fact, version 1.1 of the Namespaces recommendation says that they are deprecated.

The URI syntax only allows basic Latin letters and digits, with a few special punctuation characters. Non-Latin characters can be represented, but they must be escaped. In Namespaces 1.1, and therefore when using XML Schema 1.1, namespace names are actually IRIs (Internationalized Resource Identifiers) rather than URIs, which means that non-Latin characters can be directly represented in namespace names.

image

3.1.2. Namespace declarations and prefixes

An instance may include one or more namespace declarations that relate elements and attributes to namespaces. This happens through a prefix, which serves as a proxy for the namespace.

A namespace is declared using a special attribute whose name starts with the letters xmlns. Example 3–1 shows an instance whose root element has a namespace declaration. This declaration maps the namespace http://datypic.com/prod to the prefix prod. All of the element names in the document, namely product, number, and size, are prefixed with prod. The system attribute does not have a prefixed name, so it is not “in” the namespace.

Example 3–1. Namespace declaration


<prod:product xmlns:prod="http://datypic.com/prod">
  <prod:number>557</prod:number>
  <prod:size system="US-DRESS">10</prod:size>
</prod:product>


Prefixes are convenient because they are generally shorter than namespace names, so they make the document more readable. A more important reason for prefixes, though, is that namespace names may contain characters that are not permitted in XML names. Prefixes are constrained by the rules for XML non-colonized names, as described in Section 3.1.4 on p. 40. There is no limit to how many characters long a prefix can be, but it is best to keep prefixes short for readability.

Although the instance author may choose prefixes arbitrarily, there are commonly used prefixes for some namespaces. For example, the xsl prefix is usually mapped to the Extensible Stylesheet Language (XSL) namespace. It is legal to map the prefix bob to the XSL namespace and write a stylesheet with every XSL element name prefixed with bob. However, this is not recommended because it is confusing. For the XML Schema Namespace, the commonly used prefixes are xsd and xs.

You can declare more than one namespace in the same instance, as shown in Example 3–2. Two prefixes, ord and prod, are mapped to the namespaces http://datypic.com/ord and http://datypic.com/prod, respectively. The element names in the document are prefixed with either ord or prod to relate them to one of the two namespaces.

Example 3–2. Multiple namespace declarations


<ord:order xmlns:ord="http://datypic.com/ord"
           xmlns:prod="http://datypic.com/prod">
  <ord:number>123ABBCC123</ord:number>
  <ord:items>
    <prod:product>
      <prod:number>557</prod:number>
      <prod:size system="US-DRESS">10</prod:size>
    </prod:product>
  </ord:items>
</ord:order>


Note that number appears twice, with two different prefixes. This illustrates the usefulness of namespaces which make it obvious whether it is a product number or an order number. In most cases, the two can be distinguished based on their context in the instance, but not always.

You do not need to declare xmlns:ord and xmlns:prod as attributes in the order element declaration in your schema. In fact, it is illegal to declare them. All schema processors understand that attributes prefixed with xmlns and the unprefixed attribute with the name xmlns are always permitted.

3.1.3. Default namespace declarations

An instance may also include a default namespace declaration that maps unprefixed element names to a namespace. The default namespace declaration uses the attribute xmlns, with no colon or prefix. In Example 3–3, the start order tag contains a default namespace declaration. This declaration relates the namespace http://datypic.com/ord to all of the unprefixed element names in the document, namely order, number, and items.

Example 3–3. Default namespace declaration


<order xmlns="http://datypic.com/ord"
       xmlns:prod="http://datypic.com/prod">
  <number>123ABBCC123</number>
  <items>
    <prod:product>
      <prod:number>557</prod:number>
      <prod:size system="US-DRESS">10</prod:size>
    </prod:product>
  </items>
</order>


Note that the default namespace declaration can be combined with other namespace declarations in the same document and even in the same tag.

Default namespace declarations do not directly apply to attributes. In this case, the system attribute, although its name is not prefixed, is not in the default namespace http://datypic.com/ord. It is not directly in any namespace at all. For further explanation of the relationship between attributes and namespaces, see Section 3.1.8 on p. 44.

3.1.4. Name terminology

In the context of namespaces, there are several different kinds of names. They include:

Qualified names, known as QNames, are names that are qualified with a namespace name. This may happen one of two ways:

1. The name contains a prefix that is mapped to a namespace. In Example 3–3, prod:product is a prefixed, qualified name.

2. The name does not contain a prefix, but there is a default namespace declared for that element. In Example 3–3, items is an unprefixed, qualified name. This applies only to elements; there is no such thing as an unprefixed, qualified attribute name, as you will see in Section 3.1.8 on p. 44.

Unqualified names, on the other hand, are names that are not in any namespace. For element names, this means they are unprefixed and there is no default namespace declaration. For attribute names, this means they are unprefixed, period.

Prefixed names are names that contain a namespace prefix, such as prod:product. Prefixed names are qualified names, assuming there is a namespace declaration for that prefix in scope.

Unprefixed names are names that do not contain a prefix, such as items. Unprefixed element names can be either qualified or unqualified, depending on whether there is a default namespace declaration.

A local name is the part of a qualified name that is not the prefix. In Example 3–3, local names include items and product.

Non-colonized names, known as NCNames, are simply XML names that do not contain colons. That means that they are case-sensitive, they may start with a letter or underscore (_), and contain letters, digits, underscores (_), dashes (-), and periods (.). They cannot start with the letters “XML” either in lower or uppercase. All local names and unprefixed names are NCNames. Prefixes are also NCNames, because they follow these same rules.

3.1.5. Scope of namespace declarations

In the previous examples, namespace declarations appeared in the start tag of the root element. Namespace declarations, including default namespace declarations, can appear in any start tag in the document. Example 3–4 shows the previous order example, but with the namespace declaration for the http://datypic.com/prod namespace moved down to the product tag.

Example 3–4. Namespace declarations in multiple tags


<order xmlns="http://datypic.com/ord">
  <number>123ABBCC123</number>
  <items>
    <prod:product xmlns:prod="http://datypic.com/prod">
      <prod:number>557</prod:number>
      <prod:size system="US-DRESS">10</prod:size>
    </prod:product>
  </items>
</order>


The scope of a namespace declaration is the element in whose start tag it appears, and all of its children, grandchildren, and so on. In Example 3–4, it would be invalid to use the prod prefix outside of the product element and its children. In Example 3–5, the second product element uses the prod prefix, which is illegal because the namespace declaration is outside its scope.

Generally, it is preferable to put all your namespace declarations in the root element’s start tag. It allows you to see at a glance what namespaces a document uses, there is no confusion about their scopes, and it keeps them from cluttering the rest of the document.

Example 3–5. Invalid prefix outside of scope


<order xmlns="http://datypic.com/ord">
  <number>123ABBCC123</number>
  <items>
    <prod:product xmlns:prod="http://datypic.com/prod">
      <prod:number>557</prod:number>
      <prod:size system="US-DRESS">10</prod:size>
    </prod:product>
    <prod:product>
      <prod:number>559</prod:number>
      <prod:size system="US-DRESS">10</prod:size>
    </prod:product>
  </items>
</order>


3.1.6. Overriding namespace declarations

Namespace declarations can also be overridden. If a namespace declaration appears within the scope of another namespace declaration with the same prefix, it overrides it. Example 3–6 illustrates this. In the order tag, the prefix prod is mapped to http://datypic.com/prod. In number, it is mapped to http://datypic.com/prod2. The second namespace declaration overrides the first within the scope of the number element. This includes the number element itself.

Example 3–6. Overriding a namespace declaration


<order xmlns="http://datypic.com/ord"
       xmlns:prod="http://datypic.com/prod">
  <number>123ABBCC123</number>
  <items>
    <prod:product>
      <prod:number xmlns:prod="http://datypic.com/prod2">
        557</prod:number>
      <prod:size system="US-DRESS">10</prod:size>
    </prod:product>
  </items>
</order>


Likewise, if a default namespace declaration appears within the scope of another default namespace declaration, it overrides it, as shown in Example 3–7. The default namespace declaration in the product start tag overrides the one on the root element, meaning that product and its children are in the http://datypic.com/prod namespace.

Example 3–7. Overriding a default namespace declaration


<order xmlns="http://datypic.com/ord">
  <number>123ABBCC123</number>
  <items>
    <product xmlns="http://datypic.com/prod">
      <number>557</number>
      <size system="US-DRESS">10</size>
    </product>
  </items>
</order>


3.1.7. Undeclaring namespaces

A default namespace declaration may also be the empty string (that is, xmlns=""). This means that unprefixed element names in its scope are not in any namespace. This can be used to essentially “undeclare” the default namespace.

Example 3–8 is similar to Example 3–7 except that it uses the empty string. This means that product and its children are in no namespace.

Example 3–8. Undeclaring a default namespace


<order xmlns="http://datypic.com/ord">
  <number>123ABBCC123</number>
  <items>
    <product xmlns="">
      <number>557</number>
      <size system="US-DRESS">10</size>
    </product>
  </items>
</order>


image

In version 1.1 (but not in 1.0), you can also undeclare a prefix by using an empty string. In Example 3–9, the namespace declaration for the ord prefix in the product start tag undeclares the one on the root element, meaning that the ord prefix is undefined within the scope of product.

Example 3–9. Undeclaring a prefixed namespace


<ord:order xmlns:ord="http://datypic.com/ord">
  <ord:number>123ABBCC123</ord:number>
  <ord:items>
    <prod:product xmlns:ord="" xmlns:prod="http://datypic.com/prod">
      <prod:number>557</prod:number>
      <prod:size system="US-DRESS">10</prod:size>
    </prod:product>
  </ord:items>
</ord:order>


image

3.1.8. Attributes and namespaces

The relationship between attributes and namespaces is slightly simpler than the relationship between elements and namespaces. Prefixed attribute names, as you would expect, are in whichever namespace is mapped to that prefix. Attributes with prefixed names are sometimes referred to as global attributes. Unprefixed attribute names, however, are never in a namespace. This is because they are not affected by default namespace declarations.

Some people make the argument that an unprefixed attribute is (or should be) in the namespace of its parent element. While it may be indirectly associated with that namespace, it is not directly in it. For the purposes of writing schemas and using other XML technologies such as XSLT and XQuery, you should treat an unprefixed attribute as if it were in no namespace at all.

Example 3–10 shows a size element that has two attributes: app:system and system. app:system is associated with the namespace http://datypic.com/app through the app prefix. The unprefixed system attribute is not in any namespace at all, despite the default namespace declaration.

Example 3–10. Two attributes with the same local name


<product xmlns="http://datypic.com/prod"
         xmlns:app="http://datypic.com/app">
  <number>557</number>
  <size app:system="R32" system="US-DRESS">10</size>
</product>


Although an element cannot have two attributes with the same name, this example is valid because the attribute names are in different namespaces (or rather, one is in a namespace and one is not), and they therefore are considered to have different names.

Example 3–11 is also valid, even though the default namespace and the namespace mapped to the prod prefix are the same. This is again because the unprefixed system attribute is not in any namespace.

Example 3–11. Two more attributes with the same local name


<product xmlns="http://datypic.com/prod"
         xmlns:prod="http://datypic.com/prod">
  <number>557</number>
  <size system="US-DRESS" prod:system="R32">10</size>
</product>


Example 3–12 shows an invalid duplication of attributes. The problem is not that two different prefixes are mapped to the same namespace; this is perfectly acceptable. However, it is not valid for an element to have two attributes with the same name that are in the same namespace, even if they have different prefixes.

Example 3–12. Invalid duplicate attributes


<product xmlns:prod="http://datypic.com/prod"
         xmlns:prod2="http://datypic.com/prod">
  <number>557</number>
  <size prod:system="US-DRESS" prod2:system="R32">10</size>
</product>


This example illustrates an important point: The prefix itself has no particular meaning. Instead, it is the namespace to which it is mapped that matters when validating and comparing names. The two qualified names prod:system and prod2:system are equal, even though the prefixes differ.

3.1.9. A summary example

To summarize our discussion of namespaces, Example 3–13 provides a more complex instance that shows various combinations of namespace declarations in different scopes.

Example 3–13. A summary example


<envelope>
  <order xmlns="http://datypic.com/ord"
         xmlns:prod="http://datypic.com/prod">
    <number>123ABBCC123</number>
    <items>
      <product xmlns="http://datypic.com/prod">
        <number prod:id="prod557">557</number>
        <name xmlns="">Short-Sleeved Linen Blouse</name>
        <prod:size system="US-DRESS">10</prod:size>
        <prod:color xmlns:prod="http://datypic.com/prod2"
                    prod:value="blue"/>
      </product>
    </items>
  </order>
</envelope>


Table 3–1 explains which namespace each name is in, and why.

Table 3–1. Explanation of the summary example

Image
Image

3.2. The relationship between namespaces and schemas

Namespaces and schemas have a many-to-many relationship.

A namespace can have names defined in any number of schemas. A namespace can exist without any schema. Some namespaces have one schema that defines its names. Other namespaces have multiple schemas. These schemas may be designed to be used together, or be completely incompatible with each other. They could present different perspectives on the same information, or be designed for different purposes such as varying levels of validation or system documentation. They could be different versions of each other. There are no rules that prevent several schemas from utilizing the same namespace, with overlapping declarations. As long as the processor does not try to validate an instance against all of them at once, this is completely legal.

A schema can declare names for any number of target namespaces. Some schemas have no target namespace at all. Other schemas are represented by composing multiple schema documents, each with its own target namespace. This is described in detail in Chapter 4.

3.3. Using namespaces in schemas

3.3.1. Target namespaces

Each schema document can declare and define components for one namespace, known as its target namespace. Every globally declared or defined component (element, attribute, type, named group, or notation) is associated with that target namespace. Example 3–14 shows a schema document that declares a target namespace of http://datypic.com/prod. Three element declarations are global, and therefore all of them are in the namespace http://datypic.com/prod. Local element declarations may or may not use the target namespace of the schema document, as described in Section 6.3 on p. 98.

Example 3–14. Declaring a target namespace


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

  <xs:element name="product" type="ProductType"/>
  <xs:element name="number" type="xs:integer"/>
  <xs:element name="size" type="SizeType"/>

  <xs:complexType name="ProductType">
    <xs:sequence>
      <xs:element ref="number"/>
      <xs:element ref="size"/>
    </xs:sequence>
  </xs:complexType>
  <!--...-->
</xs:schema>


Adding a target namespace to a schema is not just informational; the target namespace becomes an important part of the names, and it must be reflected in the instance documents. Example 3–15 shows how the elements from the previous example could appear in an instance. Since they are associated with the http://datypic.com/prod namespace, they must be qualified in some way, either through a prefix or by a default namespace declaration.

Example 3–15. Prefixed names in an instance


<prod:product xmlns:prod="http://datypic.com/prod">
  <prod:number>557</prod:number>
  <prod:size>10</prod:size>
</prod:product>


A schema document cannot have more than one target namespace. However, you can link together schema documents that have different target namespaces, using an import. This is described in Section 4.3.2 on p. 66.

If you do not plan to use namespaces, you are not required to specify a target namespace. In this case, omit the targetNamespace attribute entirely.

3.3.2. The XML Schema Namespace

Since schema documents are XML, namespaces also apply to them. For example, all the elements used in schemas, such as schema, element, and simpleType, are in the XML Schema Namespace, whose namespace name is http://www.w3.org/2001/XMLSchema. In addition, the names of the built-in simple types are in this namespace.

The prefixes most commonly mapped to this namespace are xsd or xs. It is recommended that you use one of these for clarity, although you could just as easily use any other prefix. Example 3–16 shows a schema document that maps the XML Schema Namespace to xs and prefixes all of the element names in the schema document.

Example 3–16. Declaring the XML Schema Namespace


<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="number" type="xs:integer"/>
  <xs:element name="size" type="SizeType"/>
  <xs:simpleType name="SizeType">
    <!--...-->
  </xs:simpleType>
</xs:schema>


It is interesting to note that while all the element names are prefixed, all of the attribute names are unprefixed. This is because none of the attributes in the XML Schema Namespace is declared globally. This is explained further in Section 7.4 on p. 122.

The xs prefix is also used when referring to the built-in type integer. This is because integer is a simple type that is defined in the schema for schemas, whose target namespace is the XML Schema Namespace.

Mapping a prefix such as xs to the XML Schema Namespace is one of the three options for namespace declarations in schema documents. See Section 3.3.5 on p. 52 for more information.

3.3.3. The XML Schema Instance Namespace

The XML Schema Instance Namespace is a separate namespace for the four schema-related attributes that may appear in instances. Its namespace name is http://www.w3.org/2001/XMLSchema-instance. These attributes, whose names are commonly prefixed with xsi, are: type, nil, schemaLocation, and noNamespaceSchemaLocation. They are described in Section 5.1 on p. 79.

image

3.3.4. The Version Control Namespace

The XML Schema Version Control Namespace is a namespace used by six attributes that signal to processors the conditions under which they should pay attention to particular schema components. Its namespace name is http://www.w3.org/2007/XMLSchema-versioning, and it is commonly associated with the prefix vc. Four of these attributes control the portability of implementation-defined facets and types and are covered in Section 23.5.3 on p. 642. The other two indicate versions of the XML Schema language and are described in Section 23.5.2 on p. 641.

image

3.3.5. Namespace declarations in schema documents

Schema documents must contain namespace declarations of both the XML Schema Namespace and the target namespace in order to resolve the references between schema components. There are three ways to set up the namespace declarations in your schema document, each of which is described in this section.

3.3.5.1. Map a prefix to the XML Schema Namespace

You can map the XML Schema Namespace to a prefix such as xsd or xs, and make the target namespace the default namespace. Example 3–17 shows a schema document that uses this approach. This method is used throughout this book. Its advantage is that it makes it clear which components are defined by XML Schema, especially when it comes to referencing built-in types.

Example 3–17. Prefixing the XML Schema Namespace


<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="http://datypic.com/prod"
           targetNamespace="http://datypic.com/prod">
  <xs:element name="number" type="xs:integer"/>
  <xs:element name="size" type="SizeType"/>
  <xs:simpleType name="SizeType">
    <!--...-->
  </xs:simpleType>
</xs:schema>


If your schema document does not have a target namespace, you must map a prefix to the XML Schema Namespace. Otherwise, you will have no way of referencing other schema components that are defined in your schema document. Example 3–18 shows a schema document that does not have a target namespace and defaults the XML Schema Namespace. This is invalid, because the declaration of size references the type SizeType. Since the default namespace is the XML Schema Namespace, the processor will look unsuccessfully for a definition of SizeType in the XML Schema Namespace.

Example 3–18. Invalid absence of prefixes


<schema xmlns="http://www.w3.org/2001/XMLSchema">
  <element name="number" type="integer"/>
  <element name="size" type="SizeType"/>
  <simpleType name="SizeType">
    <!--...-->
  </simpleType>
</schema>


3.3.5.2. Map a prefix to the target namespace

Another alternative is to map a prefix to the target namespace, and make the XML Schema Namespace the default namespace. Example 3–19 shows a schema document that uses this approach. The names in the declarations themselves do not need to be prefixed because they automatically become part of the target namespace. The only place the prefix is used is in references to other components. For example, the declaration of size references the type SizeType by its qualified name. If it did not prefix the name of the type, the processor would look unsuccessfully for a definition of SizeType in the XML Schema Namespace.

Example 3–19. Prefixing the target namespace


<schema xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:prod="http://datypic.com/prod"
        targetNamespace="http://datypic.com/prod">
  <element name="number" type="integer"/>
  <element name="size" type="prod:SizeType"/>
  <simpleType name="SizeType">
    <!--...-->
  </simpleType>
</schema>


If you plan to use identity constraints, you may be required to map a prefix to the target namespace. See Section 17.9 on p. 439 for more information.

3.3.5.3. Map prefixes to all namespaces

It is also possible to map prefixes to all the namespaces, as shown in Example 3–20. This has the advantage of clarity, particularly when your schema documents import other namespaces.

Example 3–20. Prefixing all namespaces


<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:prod="http://datypic.com/prod"
           targetNamespace="http://datypic.com/prod">
  <xs:element name="number" type="xs:integer"/>
  <xs:element name="size" type="prod:SizeType"/>
  <xs:simpleType name="SizeType">
    <!--...-->
  </xs:simpleType>
</xs:schema>


Note that the prefix used for the target namespace in the schema does not necessarily correspond to the prefix used in the instance document. While the schema in the previous example uses the prefix prod for the target namespace, a valid instance document could use prod, foo, or any other prefix, or make that namespace the default. It is the namespace names that must match, not prefixes.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.131.238