Cómo eliminar el atributo xmlns de un nodo distinto de la raíz en un XDocument

Situación

Estoy usando XDocument para intentar eliminar un atributo xmlns="" en el primer nodo interno :

      

Entonces, lo que quiero como resultado es:

      

Código

 doc = XDocument.Load(XmlReader.Create(inStream)); XElement inner = doc.XPathSelectElement("/*/*[1]"); if (inner != null) { inner.Attribute("xmlns").Remove(); } MemoryStream outStream = new MemoryStream(); XmlWriter writer = XmlWriter.Create(outStream); doc.Save(writer); // <--- Exception occurs here 

Problema

Al intentar guardar el documento, obtengo la siguiente excepción:

El prefijo ” no se puede redefinir de ” a ‘ http: //my.namespace ‘ dentro de la misma etiqueta de elemento de inicio.

¿Qué significa esto y qué puedo hacer para eliminar ese molesto xmlns="" ?

Notas

  • Quiero mantener el espacio de nombres del nodo raíz
  • Solo quiero que se eliminen esos xmlns específicos, no habrá otros atributos xmlns en el documento.

Actualizar

He intentado usar código inspirado en las respuestas a esta pregunta :

 inner = new XElement(inner.Name.LocalName, inner.Elements()); 

Al depurar, el atributo xmlns desaparece de él, pero obtengo la misma excepción.

Creo que el código de abajo es lo que quieres. Debe colocar cada elemento en el espacio de nombres correcto y eliminar cualquier atributo xmlns='' para los elementos afectados. La última parte es necesaria ya que de lo contrario, LINQ to XML básicamente intentará dejarle un elemento de

   

Aquí está el código:

 using System; using System.Xml.Linq; class Test { static void Main() { XDocument doc = XDocument.Load("test.xml"); // All elements with an empty namespace... foreach (var node in doc.Root.Descendants() .Where(n => n.Name.NamespaceName == "")) { // Remove the xmlns='' attribute. Note the use of // Attributes rather than Attribute, in case the // attribute doesn't exist (which it might not if we'd // created the document "manually" instead of loading // it from a file.) node.Attributes("xmlns").Remove(); // Inherit the parent namespace instead node.Name = node.Parent.Name.Namespace + node.Name.LocalName; } Console.WriteLine(doc); // Or doc.Save(...) } } 

No hay necesidad de ‘eliminar’ el atributo xmlns vacío. La razón principal por la que se agrega el atributo xmlns vacío es porque el espacio de nombres de sus childnodes está vacío (= ”) y, por lo tanto, difiere de su nodo raíz. Agregar el mismo espacio de nombres a sus hijos también resolverá este ‘efecto secundario’.

 XNamespace xmlns = XNamespace.Get("http://my.namespace"); // wrong var doc = new XElement(xmlns + "Root", new XElement("Firstelement")); // gives:    // right var doc = new XElement(xmlns + "Root", new XElement(xmlns + "Firstelement")); // gives: