2008-09-16 12 views
6

Los métodos XmlElement.Attributes.Remove * funcionan bien para los atributos arbitrarios que tienen como resultado que los atributos eliminados se eliminen de la propiedad XmlDocument.OuterXml. Sin embargo, el atributo Xmlns es diferente. Este es un ejemplo:Cómo eliminar el atributo xmlns con .NET XML API

XmlDocument doc = new XmlDocument(); 
doc.InnerXml = @"<Element1 attr1=""value1"" xmlns=""http://mynamespace.com/"" attr2=""value2""/>"; 
doc.DocumentElement.Attributes.RemoveNamedItem("attr2"); 
Console.WriteLine("xmlns attr before removal={0}", doc.DocumentElement.Attributes["xmlns"]); 
doc.DocumentElement.Attributes.RemoveNamedItem("xmlns"); 
Console.WriteLine("xmlns attr after removal={0}", doc.DocumentElement.Attributes["xmlns"]); 

La salida resultante es

xmlns attr before removal=System.Xml.XmlAttribute 
xmlns attr after removal= 
<Element1 attr1="value1" xmlns="http://mynamespace.com/" /> 

El atributo parece ser retirado de la colección de atributos, pero no se elimina de XmlDocument.OuterXml. Supongo que es por el significado especial de este atributo.

La pregunta es cómo eliminar el atributo xmlns utilizando .NET XML API. Obviamente, puedo eliminar el atributo de una representación de Cadena de esto, pero me pregunto si es posible hacer lo mismo con la API.

@Edit: estoy hablando de .NET 2.0.

+0

Acabo de tropezar con este problema. ¡Buen descubrimiento! –

Respuesta

2

.NET DOM API no es compatible con la modificación del espacio de nombres del elemento, que es lo que esencialmente estás tratando de hacer. Entonces, para resolver su problema, debe construir un nuevo documento de una forma u otra. Puede usar la misma API .NET DOM y crear un nuevo elemento sin especificar su espacio de nombres. Alternativamente, puede crear una hoja de estilo XSLT que transforme su documento original de "espacio de nombres" a uno nuevo en el que los elementos no califiquen para el espacio de nombres.

+0

No estoy seguro, pero mientras no haya una respuesta positiva, creo que es verdad. – axk

0

Sí, porque es un nombre ELEMENT, no puede eliminarlo explícitamente. Usar WriteStartElement de XmlTextWriter y WirteStartAttribute, y reemplazar el atributo con espacios vacíos probablemente hará el trabajo.

Lo estoy viendo ahora. actualizará.

1

¿No se suponía que esto eliminaría los espacios de nombres?

XmlNamespaceManager mgr = new XmlNamespaceManager("xmlnametable"); 
mgr.RemoveNamespace("prefix", "uri"); 

Pero de todos modos por la tangente aquí, el XElement, XDocument y XNameSpace clases de System.Xml.Linq espacio de nombres (.Net 3.0) son mucho mejor que el viejo modelo XmlDocument. Darle una oportunidad. Soy adicto.

+0

Gracias por la sugerencia. Definitivamente lo intentaré. – axk

0

Podemos convertir el xml en una cadena, eliminar los xmlns de esa cadena, y luego crear otro XmlDocument utilizando esta cadena, que no tendrá el espacio de nombres.

1

Vi las diversas opciones en este hilo y vine a resolver mi propia solución para eliminar los atributos xmlns en xml. Esto está funcionando correctamente y no tiene problemas:

'Remove the Equifax/Transunian/Experian root node attribute that have xmlns and load xml without xmlns attributes. 
If objXMLDom.DocumentElement.NamespaceURI <> String.Empty Then 
    objXMLDom.LoadXml(objXMLDom.OuterXml.Replace(objXMLDom.DocumentElement.NamespaceURI, "")) 
    objXMLDom.DocumentElement.RemoveAllAttributes() 
    ResponseXML = objXMLDom.OuterXml 
End If 

No hay necesidad de hacer nada más para eliminar xmlns desde XML.

2

Muchas gracias a Ali Shah, ¡este hilo resolvió mi problema perfectamente! aquí hay un C# conversión:

var dom = new XmlDocument(); 
     dom.Load("C:/ExampleFITrade.xml)); 
     var loaded = new XDocument(); 
     if (dom.DocumentElement != null) 
      if(dom.DocumentElement.NamespaceURI != String.Empty) 
      { 
       dom.LoadXml(dom.OuterXml.Replace(dom.DocumentElement.NamespaceURI, "")); 
       dom.DocumentElement.RemoveAllAttributes(); 
       loaded = XDocument.Parse(dom.OuterXml); 
      } 
1
public static string RemoveXmlns(string xml) 
{ 
    //Prepare a reader 
    StringReader stringReader = new StringReader(xml); 
    XmlTextReader xmlReader = new XmlTextReader(stringReader); 
    xmlReader.Namespaces = false; //A trick to handle special xmlns attributes as regular 
    //Build DOM 
    XmlDocument xmlDocument = new XmlDocument(); 
    xmlDocument.Load(xmlReader); 
    //Do the job 
    xmlDocument.DocumentElement.RemoveAttribute("xmlns"); 
    //Prepare a writer 
    StringWriter stringWriter = new StringWriter(); 
    XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter); 
    //Optional: Make an output nice ;) 
    xmlWriter.Formatting = Formatting.Indented; 
    xmlWriter.IndentChar = ' '; 
    xmlWriter.Indentation = 2; 
    //Build output 
    xmlDocument.Save(xmlWriter); 
    return stringWriter.ToString(); 
} 
+2

Una pequeña descripción narrativa de la respuesta propuesta sería útil. – Rob

0

aquí es mi solución en vb.net chicos!

Dim pathXmlTransformado As String = "C:\Fisconet4\process\11790941000192\2015\3\28\38387-1\38387_transformado.xml" 
    Dim nfeXML As New XmlDocument 
    Dim loaded As New XDocument 

    nfeXML.Load(pathXmlTransformado) 

    nfeXML.LoadXml(nfeXML.OuterXml.Replace(nfeXML.DocumentElement.NamespaceURI, "")) 
    nfeXML.DocumentElement.RemoveAllAttributes() 

    Dim dhCont As XmlNode = nfeXML.CreateElement("dhCont") 
    Dim xJust As XmlNode = nfeXML.CreateElement("xJust") 
    dhCont.InnerXml = 123 
    xJust.InnerXml = 123777 

    nfeXML.GetElementsByTagName("ide")(0).AppendChild(dhCont) 
    nfeXML.GetElementsByTagName("ide")(0).AppendChild(xJust) 

    nfeXML.Save("C:\Fisconet4\process\11790941000192\2015\3\28\38387-1\teste.xml") 
Cuestiones relacionadas