views:

652

answers:

2

Whenever I insert an element into my xml document, the system adds an xmlns="" attribute to it. How do i get rid of it? Why is it there? Im using very simple linqtoxml.

I've got a simple XML file (Note there is no Xml declaration line and it contains a namespace):

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
  <PropertyGroup>
  </PropertyGroup>
</Project>

I do the following:

        //  1. Read in the Xml file
        XDocument testXml = XDocument.Load(@"C:\test.xml");

        //  2. Add in the extra node
  XNamespace ns = testXml.Root.Attribute("xmlns").Value;          // Get the existing namespace
        XElement newElement = new XElement("MyNewElement", "12345");    // Create the new element
        testXml.Element( ns + "Project").Add( newElement );    // Insert the new element into the document

        //  3. Write To Disk (without the xml header line)
        TextWriter tw = File.CreateText(@"C:\test2.xml");
        tw.Write(testXml.ToString());
        tw.Close();

When viewing the file i get:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
  <PropertyGroup></PropertyGroup>
  <MyNewElement xmlns="">12345</MyNewElement>
</Project>

I need to get rid of the xmlns="" bit. I believe one needs to include the namespace when adding the new element because the original document has a namespace. I tried to insert the element with :

    testXml.Element( "Project").Add( newElement );

but it kept giving me a null referece exception which im assuming it's because the element needs the namespace name.

I thought of parsing it a second time and deleting all the xmlns="" properties, but it doesn't seem to work; I keep getting the null reference exception. There is probably some fundamental understanding of namespaces im lacking here, but ive looked around and cant seem to find any hints.

Can anyone point me in the right direction wth this?

Cheers Jack.

+1  A: 

XmlNs is "XML NameSpace" - basically the idea is the same as C++ namespaces, Java/C# packages, etc, except it's for parsing against varying XML Schemas (eg XSD, DTD).

You are creating MyNewElement without specifying its namespace, so your DOM tree is interpreting that to be the blank namespace. Since your document root specifies a non-blank namespace, the xmlns="" declaration it is inserting is correct according to your code. You need to specify the namespace on your MyNewElement before adding it to the document somehow. I'm not familiar with the LinQ XML API, but I know that in one earlier version of the .Net XML parsers, recommended practice was to use a CreateElement() call from an XmlDocument instance to correctly hoist in those settings.

Just on a wild guess based on the lookup code for the Project element, and not knowing LinQ at all, try changing:

XElement newElement = new XElement("MyNewElement", "12345");

to:

XElement newElement = new XElement(ns + "MyNewElement", "12345");
Not Sure
A: 

This is not an answer to the question but I still wanted it to tell you.

You can save an xdocument to a file with the save method:

XDocument testXml = XDocument.Load(@"C:\test.xml");
...
testXml.Save(@"c:\test.xml");

No need to use a TextWriter.

tuinstoel