Share via


XNames and Expanded Names

At  my XLinq PDC2005 talk and in the XLinq Overview Documentone of the differences I mentioned between XLinq and DOM is the treatment of XML Names in XLinq.  XLinq's abstraction for XML Names is a class called XName which is the only way an XML Name shows up anywhere in the API.  You seldom have to construct an XName since there is an implicit conversion from string.  For example to construct an XElement with a local name Foo that has a namespace of https://myCompany.com you could do the following:

XElement foo = new XElement(" {https://myCompany.com}Foo",  ... any value or children of Foo ...);

So what is that string there with the curly braces in the constructor you ask?  XLinq calls it the Expanded Name.  This idea is very much inspired by James Clark's paper on XML Namespaces in which he talks about Universal Names defined as a local name and a qualifying URI.  In his article he shows that XML Names are fundamentally these Universal Names (or what XLinq calls Expanded Names) and prefixes/default namespaces are simply shorthand for representing this full name (in a way that would work with XML 1.0 since XML was initially defined without XML Namespaces).   He gives example in his paper of how default namespaces and prefixes map into Universal Names. 

This is essentially what XLinq does in its API.  When the XML is loaded into memory the default namespaces and prefixes are resolved to their corresponding Expanded Names and that is they way you deal with them in the API, via XNames.   Namespace declarations (xmlns attributes) are retained as attributes in the in-memory tree and on output are used to associate prefixes with namespaces all over again.  In other words from XLinq's perspective default namespace declarations and prefix declarations are purely serialization options.  If you want to associate a prefix with a namespace in your output, say when creating a document from scratch, then you add an xmlns attribute right where you want the prefix defined.  There are helper methods in XLinq  planned (CreateNamespacePrefix, CreateDefaultNamespaceDecl - or something) but I put some notes at the end of the XLinq overview doc on how to do that manually if needed.  The only trick is knowing the namespace of the xmlns attribute (https://www.w3.org/2000/xmlns).  For example to declare the prefix ns and associate it with https://myCompany.com you could add the following attribute where you want it defined.

new XAttribute("{https://www.w3.org/2000/xmlns/}ns", https://myCompany.com),

Anyway, I think James Clarks article on XML Namespaces is one of the better explanations on the subject and understanding that XML Names are really namespace+local name simplifies working with names in XLinq. I find that the XML code that I write, which pretty much always has namespaces involved, is quite a bit clearer and cleaner than the equivalent DOM code.

This is an area we are looking for feedback. Lemme know what you think.

cya,
rem