tags:

views:

1161

answers:

3

I'm trying to create a sitemap using Linq to Xml, but am getting an empty namespace attribute, which I would like to get rid of. e.g.

XNamespace ns = "http://www.sitemaps.org/schemas/sitemap/0.9";

XDocument xdoc = new XDocument(new XDeclaration("1.0", "utf-8", "true"),
    new XElement(ns + "urlset",

    new XElement("url",
        new XElement("loc", "http://www.example.com/page"),
        new XElement("lastmod", "2008-09-14"))));

The result is ...

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"&gt;
  <url xmlns="">
    <loc>http://www.example.com/page&lt;/loc&gt;
    <lastmod>2008-09-14</lastmod>
  </url>
</urlset>

I would rather not have the xmlns="" on the url element. I can strip it out using Replace on the final xdoc.ToString(), but is there a more correct way?

+1  A: 

If one element uses a namespace, they all must use one. In case you don't define one on your own the framework will add a empty namespace as you have noticed. And, sadly, there is no switch or something similiar to suppress this "feature".

So, there seems to be no better method as to strip it out. Using Replace(" xmlns=\"\"", "") could be a little bit faster than executing a RegEx.

Anheledir
+20  A: 

The "more correct way" would be:

XDocument xdoc = new XDocument(new XDeclaration("1.0", "utf-8", "true"),
new XElement(ns + "urlset",
new XElement(ns + "url",
    new XElement(ns + "loc", "http://www.example.com/page"),
    new XElement(ns + "lastmod", "2008-09-14"))));

Same as your code, but with the "ns +" before every element name that needs to be in the sitemap namespace. It's smart enough not to put any unnecessary namespace declarations in the resulting XML, so the result is:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"&gt;
  <url>
    <loc>http://www.example.com/page&lt;/loc&gt;
    <lastmod>2008-09-14</lastmod>
  </url>
</urlset>

which is, if I'm not mistaken, what you want.

Micah
Very nice. Thanks.
porum
+2  A: 

I stumbled across this post while dealing with a similar problem in VB.NET. I was using XML literals and it took me some searching to figure out how to make this solution work with the XML literal construction and not just the functional construction.

The solution is to import the XML namespace at the top of the file.

Imports <xmlns:ns="x-schema:tsSchema.xml">

And then prefix all of my XML literals in the query expression with the imported namespace. This removes the empty namespace that were appearing on the elements when I saved my output.

Dim output As XDocument = <?xml version="1.0" encoding="utf-8"?>
                              <XML ID="Microsoft Search Thesaurus">
                                  <thesaurus xmlns="x-schema:tsSchema.xml">
                                      <diacritics_sensitive>0</diacritics_sensitive>
                                      <%= From tg In termGroups _
                                          Select <ns:expansion>
                                                     <%= From t In tg _
                                                         Select <ns:sub><%= t %></ns:sub> %>
                                                 </ns:expansion> %>
                                  </thesaurus>
                              </XML>

    output.Save("C:\thesaurus.xml")

I hope this helps someone. Despite bumps in the road like this, the XLinq API is pretty darn cool.