Another summary I wrote for other purposes because I couldn't find it on the Web. This stuff is hard to write about. Feel free to correct me if you see something off (in fact, please do).
***
INTRODUCTION
Namespaces allow you to combine elements from multiple domains (i.e., namespaces) in the same XML instance. Even if the instances you encounter don't combine multiple namespaces, you still have to understand namespaces to work with XML that uses W3C XML Schema.
First, some terminology.
<MYNS:document xmlns:MYNS="http://www.mydomain.com">
- http://www.mydomain.com" is the namespace.
- "MYNS" is the namespace prefix.
- mlns:MYNS="http://www.mydomain.com" is the namespace declaration (an attribute and its declared value).
All XML elements belong to a namespace domain. Often you can guess what this is by looking at the element's prefix. Elements without a prefix are part of the default namespace for the instance. You can't guess what the default namespace for an instance is - you have to look for the default namespace declaration. If there is no default namespace declaration, then there is a namespace - it's just null. (Null is not the same thing as not existing.)
When you set the the default namespace, it applies to the current element and all its descendents. However, you can switch the default namespace on a descendent node by resetting the xmlns attribute to a new value. I've never seen this done in the real world.
If you aren't aware that the namespace can be defaulted, writing namespace-aware software (all schema-aware software is namespace-aware) causes confusing problems. For example, if an instance has the default namespace of "http://mydomain.com", then you need to make sure your code's references to its elements also specify that namespace. In XSLT, this means assigning a namespace prefix to the domain, and referencing the element with the prefix included. So, your code might reference <MYNS:document> even though the instance contains <document>.
The same prefix could be used in two different instances but for two different domains. Again, this can cause issues for software processing if you're not careful. If two different instances contain <MYNS:document> elements, but in one instance MYNS is mapped to http://www.mydomain.com and in the other to http://www.yourdomain.com, then those elements are NOT the same element, and software must be written accordingly. In XSLT, for example, you would declare both the namespaces, but use two different prefixes to reference the domains used in the two instances. So, your software might reference <YOURNS:document> in order to manipulate elements that look like <MYNS:document> in one of the instances.
DECLARING NAMESPACES
Namespaces are declared through attributes with the xmlns prefix. (Note that W3C XML Schemas and XSLT scripts are XML instances, so this applies to them as well.)
Most of the time, you will encounter namespace declarations like this:
<MYNS:document xmlns:MYNS="http://www.mydomain.com">
<MYNS:para>Some text</MYNS:para>
</MYNS:document>
The prefix you want to use is given the xmlns prefix and assigned to the namespace domain. The namespace declaration is included in the instance either on the current element or one of its ancestors.
To set the namespace default, you do the same thing, but the prefix you are assigning is the null one (xmlns is a prefix to nothing!):
<document xmlns="http://www.mydomain.com">
<para>Some text</para>
</document>
In this instance, any element without a prefix is part of the http://www.mydomain.com namespace.
A namespace prefix only needs to be declared once in an instance that uses it. An instance is not well-formed if a namespace prefix is used with no declaration, or if the declaration is not on the current or an ancestral element.
ATTRIBUTES AND NAMESPACES
Attributes can have a namespace prefix just like elements can. But, attributes don’t follow the same rules as elements regarding namespace declarations. If you set a default namespace for an instance, you must still explicitly declare the prefix for the instance's attributes. For example, in this:
<myElement xmlns="http://www.mydomain.com" myAttribute="1234" /> myElement is part of the mydomain namespace, but myAttribute has the default (null) namespace. To make myAttribute part of mydomain, you would need to do this instead:
<myElement xmlns="http://www.mydomain.com"
xmlns:MYNS="http://www.mydomain.com"
MYNS:myAttribute="1234" />
This makes sense if you think it through (couldn't really work any other way).
REFERENCING SCHEMAS
There are two ways to reference schemas. Both use an attribute to point to the schema location. The attributes belongs to a reserved w3c namespace domain, which is almost always referenced with the "xsi" prefix.
1. THE xsi:schemaLocation ATTRIBUTE
Schemas can (optionally) include what is called a target namespace. It is declared using the targetNamespace attribute on the root <schema> element. This is the namespace for elements defined in the schema. If an XML instance references a schema with a declared target namespace, then its elements must belong to the same namespace.
When a target namespace is declared in the schema, instances must use the schemaLocation attribute to reference the schema, and the default namespace for the instance must be set to the schema target namespace.
<document xmlns='http://www.mydomain.com'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='http://www.domain.com/schema.xsd'> ...
</document>
The default namespace declaration (the xmlns attribute) points to the schema target namespace.
The schemaLocation attribute points to the schema location.
2. THE noNamespaceSchemaLocation ATTRIBUTE
If a schema doesn't include a declared target namespace, then it belongs to the null namespace. Instances using the schema must also keep the default namespace as as the null namespace, and should use the noNamespaceSchemaLocation attribute to point to the schema.
<document xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:noNamespaceSchemaLocation='http://www.domain.com/schema.xsd'> ...
</document>
No default namespace is declared (and so it is null), and the noNamespaceSchemaLocation attribute points to the schema location.
Recent Comments