XML Tutorial
Volume 10 : XML Namespaces
Yasuhiro Nonaka
We will be discussing "XML Namespace" in this volume. XML Namespace is a mechanism to avoid name conflicts by differentiating elements or attributes within an XML document that may have identical names, but different definitions. We will be covering the basics of namespace, including declaration methods, scope, attribute namespace, and default namespace. Namespace is one of the more difficult areas of XML, but it is required knowledge for passing the Basic V2 Exam, and programmers, as well as exam candidates, need to obtain a solid understanding of the concepts.
Index
What is Namespace? Why is it necessary?
Namespace Declaration
Default Namespace
Review Questions
What is Namespace? Why is it necessary?
As an example, let's assume we have an RDB with a table of the following structure (employeeTable, sectionTable). What kind of SQL statement would you create to obtain a list of Employee ID, Employee Department Name, and Employee Name? If we merged employeeTable and sectionTable with the secID column, then we would be able to obtain a list of employee IDs, employee departments and employee names. However, since the name column and secID column exist in both tables, we would have to designate the table name before the name and secID columns, or designate the alias of the table in order to clarify the table of the name and secID columns in question.
So, what happens when this data is expressed in an XML document? Let's take two XML documents, and see how we can create a list showing employee ID, employee department and employee name using XML.
First, we will create a root element (employeeList element) and an element (personList element) to summarize employee information for one individual. You might have thought about creating an employee ID element (empID element in employeeXML document), department name element (name element in sectionXML document) and an employee name element (name element in employeeXML document) as child elements, but there's a problem with this method. The problem is an "element name conflict." The name element in the employee XML document is defined as an element representing the employee's name, whereas the name element of the section XML document is defined as an element representing a department name. In merging these two XML documents, you will get a name element that has two separate meanings. While a human might be able to tell the difference between these two "name" elements and what they represent, computer systems cannot determine what these name elements are supposed to mean. The XML 1.0 specification never considered the merging of different types of XML documents (vocabularies) to create a new XML document, which led to this type of name conflict problem.
employeeXML Document
<employee>
<personInfo>
<empID>E0000001</empID>
<secID>S001</secID>
<name>John Smith</name>
</personInfo>
<personInfo>
<empID>E0000002</empID>
<secID>S002</secID>
<name>Ichiro Tanaka</name>
</personInfo>
・
・
・
</employee>
sectionXML Document
<section>
<sectionInfo>
<secID>S001</secID>
<name>Sales</name>
</sectionInfo>
<sectionInfo>
<secID>S002</secID>
<name>Development</name>
</sectionInfo>
・
・
・
</section>
employeeListXML Document
<employeeList>
<personList>
<empID>E0000001</empID>
<name>Sales</name>
<name>John Smith</name>
</personList>
<personList>
<empID>E0000002</empID>
<name>Development</name>
<name>Ichiro Tanaka</name>
</personList>
・
・
・
</employeeList>
The name element expressing employee name and the name element expressing department name conflict!
Avoiding Element Name Conflicts
Perhaps some of you out there had the idea that element name conflicts can be avoided by applying the same type of alias used for RDB table merge explained above to an XML document. The W3C recommended a specification called "Namespaces in XML," whereby XML vocabularies are mutually differentiated, allowing for the re-use of a vocabulary. Utilizing this XML namespace allows us to avoid any element name conflicts.
Here, we will add an XML namespace declaration and description in both the employee data XML document and section data XML document. Next, we will merge these two XML documents, and create a new employeeList data XML document. As a result, we can differentiate the "emp:name element" of the employeeList data XML document as an element representing employee name, and the "sec:name element" as an element representing department name. It might be easiest to think of one namespace as an aggregation of elements and attributes.
Employee XML Document
<emp:employee xmlns:emp="urn:corp:emp">
<emp:personInfo>
<emp:empID>E0000001</emp:empID>
<emp:secID>S001</emp:secID>
<emp:name>John Smith</emp:name>
</emp:personInfo>
<emp:personInfo>
<emp:empID>E0000002</emp:empID>
<emp:secID>S002</emp:secID>
<emp:name>Ichiro Tanaka</emp:name>
</emp:personInfo>
・
・
</emp:employee>
section XML Document
<sec:section xmlns:sec="urn:corp:sec">
<sec:sectionInfo>
<sec:secID>S001</sec:secID>
<sec:name>Sales</sec:name>
</sec:sectionInfo>
<sec:sectionInfo>
<sec:secID>S002</sec:secID>
<sec:name>Development</sec:name>
</sec:sectionInfo>
・
・
</sec:section>
employeeList XML Document
<list:employeeList xmlns:list="urn:corp:list"
xmlns:emp="urn:corp:emp"
xmlns:sec="urn:corp:sec">
<list:personList>
<emp:empID>E0000001</emp:empID>
<sec:name>Sales</sec:name>
<emp:name>John Smith</emp:name>
</list:personList>
<list:personList>
<emp:empID>E0000002</emp:empID>
<sec:name>Development</sec:name>
<emp:name>Ichiro Tanaka</emp:name>
</list:personList>
・
・
</list:employeeList>
Namespace Declaration
Write a namespace declaration according to the following description method, describing the element start tag:
If the element and/ or attribute belong to a namespace, a colon (":") is placed between the namespace prefix and the element name/ attribute name.
As a test, let's take the previous employeeList XML document as an example, and provide a namespace declaration and an element belonging to the namespace.
<emp:personInfo>
…(omitted)…
</emp:personInfo>
</emp:employee>
In this example, we have declared the namespace prefix as "emp", and the namespace identifier (URI) as "urn:corp:emp". This means that element names and attribute names with the "emp" prefix (including the employee element) all belong to the urn:corp:emp namespace.
If the namespace prefix is not provided for an element and/ or attribute name, except for cases where a default namespace is declared (to be discussed later), the element name and/ or attribute name do not belong to a namespace. While the namespace declaration is described as a start tag attribute, this is different than a regular attribute. Elements having only an "xmlns:~" description have a namespace declaration, but no attribute.
Any arbitrary text string can be used as a namespace prefix; since there is no special meaning, any text string will do. However, the URI must be universally unique. Quite often a URL beginning with "http://~" is used in practice. Since the URL is not actually accessed, it is not a problem if the file, etc. does not really exist. Understand that a URI represents nothing more than a logical namespace name.
Namespace Declaration Scope
The namespace declaration scope is the scope for which the namespace prefix declared in a namespace declaration can be described. This scope covers the element and element content (from the element start tag to the end tag) for which the namespace declaration has been written. A namespace prefix can be written for an element or descendant element for which a namespace has been declared, or for an attribute defined therein.
A separate namespace declaration can be made for the descendant element of an element for which a namespace declaration has already been made, and a different namespace prefix within that scope can be used as well.
In addition to highest-order elements, namespace declarations can also be made in discrete sections. However, the same namespace declaration would have to be repeated many times, making the XML document difficult to follow. In this type of situation, it is best to make a collective set of namespace declarations in the highest-order element, as shown in the LIST1 example.
LIST1
<list:employeeList xmlns:list="urn:corp:list" xmlns:emp="urn:corp:emp" xmlns:sec="urn:corp:sec">
<list:personList>
<emp:empID>E0000001</emp:empID>
<sec:name>Sales</sec:name>
<emp:name>John Smith</emp:name>
</list:personList>
<list:personList>
<emp:empID>E0000002</emp:empID>
<sec:name>Development</sec:name>
<emp:name>Ichiro Tanaka</emp:name>
</list:personList>
<list:personList>
<emp:empID>E0000003</emp:empID>
<sec:name>Development</sec:name>
<emp:name>Jiro Suzuki</emp:name>
</list:personList>
<list:personList>
<emp:empID>E0000004</emp:empID>
<sec:name>Administrative</sec:name>
<emp:name>Saburo Takahashi</emp:name>
</list:personList>
</list:employeeList>
Namespaces with Attributes
Attributes can either belong to the same namespace of the element for which the attribute is defined, or belong to a completely different namespace than that to which the element belongs. The definition for an attribute that belongs to a namespace is the same as that for elements, with the "namespacePrefix:" notation coming before the attribute name. If no namespace prefix is provided for the attribute name, the attribute will not belong to any namespace.
●Attribute belongs to same namespace as the element
<emp:personInfo emp:empID="E0000001">
<emp:secID>S001</emp:secID>
<emp:name>John Smith</emp:name>
</emp:personInfo>
</emp:employee>
●Attribute belongs to different namespace than the element
<emp:personInfo work:empID="E0000001"
xmlns:work="urn:corp:work">
<emp:secID>S001</emp:secID>
<emp:name>John Smith</emp:name>
</emp:personInfo>
</emp:employee>
●Attribute does not belong to any namespace
<emp:personInfo empID="E0000001">
<emp:secID>S001</emp:secID>
<emp:name>John Smith</emp:name>
</emp:personInfo>
</emp:employee>
What must be noted here is that under the XML 1.0 specification, attributes with the same name cannot be written within the same element. However, for XML documents conforming to the Namespaces in XML specification, the combination of namespace identifier and attribute name is what determines whether an attribute is duplicated. Accordingly, if the namespace identifier is different, attributes having the same attribute name are considered to be different.
●The example below throws an error under the XML 1.0 specification
<personInfo empID="E0000001" empID="S0000001">
<secID>S001</secID>
<name>John Smith</name>
</personInfo>
</employee>
●The example below does not throw an error, since the Namespaces in XML specification is used
xmlns:work="urn:corp:work">
<emp:personInfo emp:empID="E0000001"
work:empID="S0000001">
<emp:secID>S001</emp:secID>
<emp:name>John Smith</emp:name>
</emp:personInfo>
</emp:employee>
Default Namespaces
A "default namespace" is a namespace declaration that does not use a namespace prefix (See Figure 11 for notation method). The scope of the default namespace is the element for which the namespace was declared and the related content, just as with the namespace scope discussed earlier. The benefit of using a default namespace is that the namespace prefix can be omitted.
For example, when adding a new namespace to an existing XML document, writing a namespace prefix for each element to which the new namespace will be applied involves a tremendous amount of tedious work. The larger the XML document, the greater the labor involved, and the greater the likelihood of notation errors. In this type of situation, adding only a default namespace declaration to the XML document in question eliminates the need to write a namespace prefix for each and every element, saving a lot of time.
On the other hand, there are drawbacks. One drawback is that omitting the namespace prefix makes it more difficult to understand which element belongs to which namespace, and which namespace is applicable. In addition, programmers should remember that when a default namespace is declared, the namespace is applied only to the element, and not to any attributes.
Overwriting a Default Namespace
A default namespace can be overwritten partially by declaring a completely different default namespace within the scope of the original default namespace. A default namespace can be canceled using the following notation method:
Notation to cancel a default namespace
The xmlns="" designation frees an element within the namespace scope from belonging to any namespace. A namespace using a namespace prefix can be designated within the scope of a default namespace.
Review Questions
Question 1
Select which of the following correctly describes the namespace to which the "ProductInformation" element belongs, given the XML Document "product.xml" below.
[product.xml]
<?xml version="1.0" ?>
<inf:ProductInformation xmlns:inf="urn:product:Info"
xmlns:stk="urn:product:Stock">
<inf:ProductName Code="C00001">Computer</inf:ProductName>
<inf:Price Units="$">2500</inf:Price>
<stk:Volume Units="Units">200</stk:Volume>
</inf:ProductInformation>
- urn:product:Info
- urn:product:Stock
- urn:product:Info、urn:product:Stock
- There is no namespace to which the "ProductInformation" element belongs
Comments
For the "ProductInformation" element, two namespaces have been declared: the namespace "urn:product:Info" with the namespace prefix "inf", and the namespace "urn:product:Stock" with the namespace prefix "stk". The "ProductInformation" element has the namespace prefix "inf", and as such, the "ProductInformation" element belongs to the namespace "urn:product:Info". Accordingly, the correct answer is A.
Question 2
Select which of the following correctly describes the namespace to which the "Code" attribute of the "ProductName" element belongs, given the XML Document "stock.xml" below.
[stock.xml]
<?xml version="1.0" ?>
<stk:InventoryInfo xmlns:stk="urn:product:Stock"
xmlns:inf="urn:product:Info">
<stk:ProductName inf:Code="X00101">Notebook PC</stk:ProductName>
<stk:Price>300000</stk:Price>
<stk:Volume>500</stk:Volume>
</stk:InventoryInfo>
- urn:product:Stock
- urn:product:Info
- urn:product:Stock、urn:product:Info
- There is no namespace to which the "Code" attribute belongs
Comments
First, we confirm the namespace declaration in the XML document. Two namespaces have been declared for the "InventoryInfo" element: the namespace "urn:product;Stock" with the namespace prefix "stk", and the namespace "urn:product:Info" with the namespace prefix "inf". If an attribute is to belong to a namespace, then the "namespaceprefix:" notation must come at the beginning of the attribute name. Since the "Code" attribute of the "ProductName" element has the "inf" namespace prefix, it belongs to the "urn:product:Info" namespace. Accordingly, the correct answer is B.
Question 3
Select which of the following correctly describes the namespace to which the "Units" attribute of the "Price" element belongs, given the XML Document "sales.xml" below.
[sales.xml]
<?xml version="1.0" ?>
<SalesInfo xmlns="urn:product:Details"
xmlns:sls="urn:product:Sales">
<ProductName Code="C00001">Computer</ProductName>
<Price Units="$">2500</Price>
<Volume Units="Units">200</Volume>
</SalesInfo>
- urn:product:Details
- urn:product:Sales
- urn:product:Details、urn:product:Sales
- There is no namespace to which the "Units" attribute of the "Price" element belongs
Comments
The default namespace "urn:product:Details" and the namespace "urn:product:Sales" with the namespace prefix "sls" have been declared for the "SalesInfo" element. Since a default namespace has been declared, any element without a namespace prefix belongs to this namespace.
Since attributes do not apply to default namespaces, the "Code" attribute of the "ProductName" element and the "Units" attributes of the "Price" element and "Volume" element do not belong to any namespace declared in this XML document. Accordingly, the correct answer is D.
Question 4
Select which of the following correctly describes the namespace to which the "ProductName" element belongs, given the XML Document "product.xml" below.
[product.xml]
<?xml version="1.0" ?>
<ProductInfo xmlns="urn:product:Info"
xmlns:stk="urn:product:Stock">
<ProductName Code="C00001" xmlns="">Computer</ProductName>
<Price>250000</Price>
<Volume>200</Volume>
</ProductInfo>
- urn:product:Info
- urn:product:Stock
- urn:product:Info、urn:product:Stock
- There is no namespace to which the "ProductName" element belongs
Comments
First, we confirm the namespace declarations in this XML document. Two namespaces have been declared for the "ProductInfo" element: the default namespace "urn:product:Info" and the namespace "urn:product:Stock" with the namespace prefix "skt". As with Question 3 above, any element that has not namespace prefix belongs to the default namespace. However, the "xmlns="" " notation of the "ProductName" element cancels the default namespace. Accordingly the "ProductName" element does not belong to any namespace.
However, in this case, the scope of the default namespace cancellation only relates as far as the "ProductName" element, so the "Price" element and "Volume" element namespaces are unaffected. Accordingly, the correct answer is D.
Yasuhiro Nonaka
Infoteria Corporation Training Department. After working in systems development for more than a decade, Mr. Nonaka now mainly oversees the text development and revision of the Infoteria certification training course corresponding to the "XML Master Basic V2" exam.Mr. Nonaka's most recent goal is to visit the health club twice per week, up from his current pace of 0 to 1 times per month.
The content presented here is an HTML version of an article that originally appeared in the December 2007 issue of DB Magazine published by Shoeisya.