views:

222

answers:

4

Something confuses me here:

The NSXMLParser method has a namespaceURI attribute:

- (void)parser:(NSXMLParser *)parser 
 didEndElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI 
 qualifiedName:(NSString *)qName

From the documentation I couldn't figure out what they mean by "namespace". Can someone explain with an example what a namespace is in a XML and why I would want that?

Edit: Yep, I noticed wikipedia. But it's confusing, again. What sense does it make to put one single namespace declaration at the top of the XML file like

xmlns:xhtml="http://www.w3.org/1999/xhtml"

?? Again, that makes just zero sense. Wikipedia has no useful example either to get it, why I would really want namespaces and -more importantly- how this looks in an XML file. They say it's for resolving ambiguity of multiple same-named elements like ID, but there's no example how multiple namespaces would resolve that.

+3  A: 

See http://en.wikipedia.org/wiki/XML_namespace

Ole Begemann
+7  A: 

XML namespaces work like namespaces everywhere else.

They provide a means to uniquely distinguish equally named elements or attributes. This is done by declaring a namespace URI, and optionally attaching a prefix to the node name. This prefix is (optionally) defined along with the namespace declaration.

<!-- node without any namespace (it's in the default namespace) -->
<node>
  <child /><!-- descendants are in the parent namespace by default -->
</node>

<!-- node with explicit default namespace -->
<node xmlns="http://some/namespace/uri/"&gt;
  <child /><!-- descendants are in the parent namespace by default -->
</node>

<!-- NS declaration with prefix (node is still in the default namespace!) -->
<node xmlns:prefix="http://some/namespace/uri/"&gt;
  <child /><!-- descendants are in the parent's namespace -->
  <prefix:child><!-- explicit namespace assignment by prefix -->
    <grandchild /><!-- prefixes don't propagate, this is in the default namespace! -->
  </prefix:child>
</node>

Namespaces are strictly scoped. They are available to the node and its descendants only. To have a namespace available in the entire XML document, it must be declared at the top level element (document element).

In your case, on the example or <prefix:child />:

didEndElement = "child"
 namespaceURI = "http://some/namespace/uri/"
qualifiedName = "prefix:child"
Tomalak
And just to clarify: In <prefix:node><child /></prefix:node> child still has the default namespace, not the namespace linked to the prefix.
Bart van Heukelom
@Bart: Very true, I'll change the description.
Tomalak
Cool, +1 then :)
Bart van Heukelom
+2  A: 

Namespaces are used to qualify your element names, prefixes are used to simplify you XML. By default, there is an namespace with an "empty" uri.

Expanding Tomalaks example:

<!-- Mixing namespaces default namespace -->
<node xmlns:gc="http://other/namespace/gc"&gt; <!-- node is in default NS -->
  <child> <!-- child is still in default NS, inherited from parent - node -->
    <gc:grandchild/>  <!-- grandchild is in the "http://other/namespace/gc", because of gc prefix -->
  </child>
  <child xmlns="http://some/namespace/uri/" xmlns:gc2="http://other/namespace/gc"&gt; <!-- node is in "http://home/namespace/uri" because of declration -->
    <gc2:grandchild/> <!-- again, in "http://other/namespace/gc", despite different prefix -->
    <grandchild/> <!-- yet this one is in "http://home/namespace/uri", no prefix, inherited from parent -->
  </child>
</node>

The take away here is that both "child" node are DIFFERENT NODES. They look the same, but their "fully qualified names" are different". This is particularly important in XSL.

Same with the grandchildren. gc:grandchild and gc2:grandchild are THE SAME, they share the same Namespace URI, but use different prefixes. The third grandchild node is different, as it's using its inherited namespace from the parent child node.

Namespaces are important because they let you "mix and match" xml in a single document from different vocabularies. For example embedding SVG markup within an XHTML document. Using namespaces prevents having overlap of the same base node names.

For most simple XML problems, they are unnecessary. But when you start merging standards, etc. they become very important.

Another example is embedding SAML assertions within SOAP envelopes for web services. SOAP is one standard, SAML is another -- independent standards and standard bodies, but both allow areas of "arbitrary XML" to be inserted in their documents. Namespaces keep the content separate.

Will Hartung
+1  A: 

Namespaces are important in XML as you may have nodes that have the same local-name in the same xml hierarchy.

Imagine an xml document that describes a journal article. You might have a element that defines the author(s) of the article:

<article>
  <head>
    <author>Emily Berthenstien</author>
  </head>
....

Further down the article you may have citations that list authors that have been cited.

<citations>
  <citation>
    <author>Bernard Rightofen</author>
  </citation>  
</citations>       

How do you distinguish the 2 "author" nodes?

Adding a different namespace to the "author" element in the head and the citation nodes will create a QName for each of the author nodes that you can then use to access them specifically (with XPath or whatever) and not get confused. For example, you can now select only the citation authors using XPath and its QName:

declare namespace citauths="http://citation/authors/only"

//citauths:author

and just the article authors:

declare namespace auths="http://article/authors/only"

//auths:author
Pabs