erik p
erik p

Reputation: 422

Namespaces in XML

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>
  1. http://www.foo.org
  2. http://www.bar.com
  3. http://baz.net
  4. The empty string
  5. http://www.cs.au.dk/dWebTek

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

Answers (2)

bielawski
bielawski

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

potame
potame

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:

  1. 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.
  2. 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

Related Questions