Reputation: 422
I'm looking through previous exam-sets and one of the questions pertains to the usage of namespaces in an XML document. The question goes as follows:
What is the namespace of the element foo in the following XML document?
<xyz xmlns="http://baz.net" xmlns:foo="http://www.foo.org">
<namespace xmlns:xyz="http://www.foo.org"/>
<def xmlns:dwebtek="http://www.cs.au.dk/dWebTek">
<foo foo:xmlns="http://www.bar.com"/>
</def>
</xyz>
My initial thought was option 2. I noticed that they swapped foo and xmlns around in the foo element tag though. What impact does this have? Would this still be considered well-formed XML?
My second thought was then option 1, as in the xyz element tag they define the namespace for foo to "http://www.foo.org".
Checking the answer sheet however, it says the correct answer is option 3. Why is this? Could this be a mistake in the answer key? If not, why is option 2 incorrect?
EDIT: small correction
Upvotes: 1
Views: 382
Reputation: 1702
So how can you tell that potame's explanation is actually correct? It can be queried!
DECLARE @t XML = '
<xyz xmlns="http://baz.net" xmlns:foo="http://www.foo.org">
<namespace xmlns:xyz="http://www.foo.org"/>
<def xmlns:dwebtek="http://www.cs.au.dk/dWebTek">
<foo foo:xmlns="http://www.bar.com"/>
</def>
</xyz>';
-- To see the NS of the 1st foo element
select @t.value('namespace-uri((//*:foo)[1])','varchar(200)');
-- To see the NS of all foo elements
select x.n.value('namespace-uri(.)','varchar(200)') from @t.nodes('//*:foo') x(n);
Thus proof that he is.
Upvotes: 0
Reputation: 7905
The right answer is 3 indeed.
Let's review in detail what are the declared namespaces so that you can figure out why.
First line:
<xyz xmlns="http://baz.net" xmlns:foo="http://www.foo.org">
It declares two namespaces:
http://baz.net
which is the default namespace URI for all unprefixed elements. This will apply to all elements in your document, unless another xmlns
is encoutered.http://www.foo.org
, which is bound to the foo
prefix. This namespace will apply only to elements (or attributes) starting with the foo:
prefix, e.g. <foo:bar>
Second line
<namespace xmlns:xyz="http://www.foo.org"/>
It attaches the http://www.foo.org
namespace URI to the xyz
prefix. <namespace>
tag is attached to http://baz.net
namespace URI at this point, because it has no prefix.
Third line
<def xmlns:dwebtek="http://www.cs.au.dk/dWebTek">
It attaches the http://www.cs.au.dk/dWebTek
namespace URI to the dwebtek
prefix. <def>
tag is attached to http://baz.net
namespace URI at this point.
Fourth line
<foo foo:xmlns="http://www.bar.com"/>
There's a trick here, foo:xmlns
is not a namespace declaration, because it doesn't start with xmlns
. It is the attribute xmlns
, with the foo
prefix (and it's not advised to name an attribute xmlns even if here it is correct). Your element <foo>
has no prefix, it is still attached to the default namespace URI thanks to the xmlns
from the start, namely http://baz.net
(and also because another xmlns
has not been found anywhere else in the document).
Note:
With such a line in your document:
<foo xmlns="http://www.bar.com"/>
the right anwer would have been 2, this time.
Upvotes: 3