Namespaces

[Previous] [Next]

XML namespaces offer a way to create names in an XML document that are identified by a Uniform Resource Identifier (URI). By using namespaces in your XML document, you can uniquely identify elements or attributes in the document. For example, consider the following XML document fragment:

 <order> <type ordertype="New"/> <customer> <type customertype="Rich"/> </customer> </order> 

This is a valid XML document, yet it would be difficult for an application reading this document to differentiate between the type element associated with the order element and the type element associated with the customer element. Although in this instance you could change the names of the elements in the DTD and XML document, this solution is not always possible.

Let's look more closely at how these element name problems can occur. For the most part, you want the DTDs you create to be modular, meaning that they contain definitions for only one type of information. These modular DTDs can then be combined to create more complex DTDs.

NOTE
Schemas are like DTDs, except they use a different syntax than DTDs and use XML to define the structure of a set of XML documents. For a detailed discussion of schemas, see Chapter 7.

For example, you could have DTDs that define the structure of the following XML documents: Customer, Order, Order Details, Product, and Category. These DTDs can be used to create Customer, Order, Order Details, Product, and Category XML documents. You can also combine these DTDs to create a single, complete order XML DTD that contains all the detailed information about an order, including the customer, order, order details, product, and category information. The most common problem that occurs when you combine DTDs is naming conflicts between elements.

If we defined the order entity in an external file named Order.dtd and the customer entity in an external file named Customer.dtd, our example order DTD might look like this:

 <?xml version="1.0"?> <!--Order --> <!ENTITY order SYSTEM "Order.dtd"> <!--Customer --> <!ENTITY customer SYSTEM "Customer.dtd">  

When the Order and Customer entities are replaced, the DTD might look like this:

 <?xml version="1.0"?> <!--Order --> <!ELEMENT order (id, customer)> <!ELEMENT type()> <!ATTRIBUTE type ordertype CDATA "Old"> <!--Customer --> <!ELEMENT customer> <!ELEMENT type()> <!ATTRIBUTE type customertype CDATA "Rich"> 

This DTD is invalid because the type element is declared twice with two different types of attributes. This repetition is one of the potential problems of using external entities.

Namespaces enable you to solve this problem. Namespaces are defined within the elements in your XML document. If an element has child elements, the child elements can either inherit the parent's namespace or override the parent's namespace.

Namespace Prefixes

Let's begin our examination of namespaces by looking at prefixes. Each namespace has a prefix that is used as a reference to the namespace. This prefix must follow all the usual naming conventions for XML names as we discussed in Chapter 3. In addition, prefixes must not begin with xmlns or xml. You can't use xmlns because it's the keyword that's used to define a namespace, and xml can't be used because it's the processing instruction used to define attributes of an XML document.

Namespaces are declared within an element's begin tag. The syntax for declaring a namespace looks like this:

 <namespacePrefix:elementName xmlns:namespacePrefix = 'URL'> 

This particular URL does not refer to a DTD or a schema. The URL doesn't even have to point to an existing file. Its purpose is to provide a unique name to associate with the elements and attributes in the XML document. The namespace can also be identified by a URI or a URN.

Because each URL, URI, or URN is unique, using a company's URL followed by additional text should create unique identifiers for each namespace. Here is an example of this format:

 <?xml version="1.0"?> <bill:message xmlns:bill='http://www.northwindtraders.com/bill'> <bill:date>1/1/2002</bill:date> <bill:body>Your current balance is $1,999,999.00. Please pay immediately. Thank you.</bill:body> </bill:message> 

You can also declare more than one namespace in an element's begin tag, as shown here:

 <?xml version="1.0"?> <bill:message xmlns:bill='http://www.northwindtraders.com/bill' xmlns:body='http://www.northwindtraders.com/message'> <bill:date>1/1/2002</bill:date> <body:body>Your current balance is $1,999,999.00. Please pay immediately. Thank you. </body:body> </bill:message> 

In this example, the message element contains two namespace declarations: bill and body. The bill namespace is used to define the message element and the date child element. The body namespace is used to define the body child element.

Default Namespaces

A default namespace is used by an element if the element does not have a namespace prefix; this default is also used by all child elements of that element if they do not have a namespace prefix. The declaration for a default namespace looks like this:

 <elementName xmlns='URL'> 

Our earlier example could be rewritten using default namespaces as follows:

 <?xml version="1.0"?> <message xmlns='http://www.northwindtraders.com/bill' xmlns:body='http://www.northwindtraders.com/message'> <date>1/1/2002</date> <body:body>Your current balance is $1,999,999.00. Please pay immediately. Thank you. </body:body> </message> 

The first namespace is the default namespace. The default namespace is used by the message element and the date child element. The body child element still uses the body namespace.

You can also declare namespaces in the begin tag of child elements, as shown here:

 <?xml version="1.0"?> <message xmlns='http://www.northwindtraders.com/bill' xmlns:body='http://www.northwindtraders.com/message'> <date>1/1/2002</date> <body:body> <customerName xmlns='http://www.northwindtraders.com/name'> Fred Smith </customerName> Your current balance is $1,999,999.00. Please pay immediately. Thank you. </body:body> </message> 

Here the customerName child element is defined by a default namespace.

You can set the default namespace equal to an empty string (""), as shown here:

 <?xml version="1.0"?> <message xmlns="" xmlns:body='http://www.northwindtraders.com/message'> <date>1/1/2002</date> <body:body>Your current balance is $1,999,999.00. Please pay immediately. Thank you. </body:body> </message> 

If you do this, there will be no namespace associated with elements that are not preceded by a namespace prefix.

NOTE
Default namespaces apply only to elements; they do not apply to attributes.

Attributes and Namespaces

An attribute name can be used only once in an element. When you combine a namespace prefix with an attribute name, the combination must be unique. The following is acceptable:

 <?xml version="1.0"?> <message xmlns='http://www.northwindtraders.com/bill' xmlns:body='http://www.northwindtraders.com/message'> <date>1/1/2002</date> <body:body body:importance='High' importance='High'>Your current balance is $1,999,999.00. Please pay immediately. Thank you. </body:body> </message> 

In this case, the first importance attribute is associated with the body namespace, and the second importance attribute is associated with the default namespace.

Remember, you can define an element name only once in your DTD. Namespaces resolve the element naming conflicts. By using namespaces, you can reference several different documents that all use the same element names.

Declaring Namespaces in DTDs

In the preceding example, we used the tag form <body:body>. You must declare the element using this format in your DTD if a namespace is used. For example, this body element would need to be declared in your DTD as follows:

 <!ELEMENT body:body (#PCDATA)> 

If this declaration is used in an external DTD, all documents that reference this external DTD will need to use the name specified in the DTD (in this case, body:body).

You can use entities to enable users to decide whether they want to use a namespace, and if they do, what prefix they want to use. To do so, make the following declarations in your DTD:

 <!ENTITY % ns ''> <!-- Can be overridden in the internal subset of a schema document to establish a namespace prefix --> <!ELEMENT %ns;body (#PCDATA)> 

If these declarations were included in an external DTD named MessageBody.dtd, you could include the following reference in your internal DTD:

 <?xml version="1.0"?> <!DOCTYPE message [ <!ENTITY % ns 'body:'> <!ENTITY messagebody SYSTEM "MessageBody.dtd">  

The local declaration of the ns entity will override the declaration in MessageBody.dtd. Using this technique, each document that uses elements defined in an external DTD can create its own names for the namespace. Let's now move on to the other three specifications related to XML: XPath, XPointer, and XLink.



Developing XML Solutions
Developing XML Solutions (DV-MPS General)
ISBN: 0735607966
EAN: 2147483647
Year: 2000
Pages: 115
Authors: Jake Sturm

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net