Pregunta

Al generar XML a partir de XmlDocument en .NET, aparece un atributo xmlns en blanco la primera vez que se inserta un elemento sin un espacio de nombres asociado; ¿Cómo se puede prevenir esto?

Ejemplo:

XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("root",
    "whatever:name-space-1.0"));
xml.DocumentElement.AppendChild(xml.CreateElement("loner"));
Console.WriteLine(xml.OuterXml);

Salida:

<root xmlns="whatever:name-space-1.0"><loner xmlns="" /></root>

Deseado Salida:

<root xmlns="whatever:name-space-1.0"><loner /></root>

¿Existe una solución aplicable al código XmlDocument, no algo que ocurre después de convertir el documento a una cadena con OuterXml?

Mi razonamiento para hacer esto es ver si puedo igualar el XML estándar de un protocolo particular usando XML generado por XmlDocument. El <=> atributo en blanco puede no romper o confundir un analizador, pero tampoco está presente en ningún uso que haya visto de este protocolo.

¿Fue útil?

Solución

Gracias a la respuesta de Jeremy Lew y a un poco más de juego, descubrí cómo eliminar los atributos en blanco xmlns: pasar el espacio de nombres del nodo raíz al crear cualquier nodo hijo que desee que no tenga un prefijo El uso de un espacio de nombres sin un prefijo en la raíz significa que debe usar ese mismo espacio de nombres en los elementos secundarios para que ellos también no tengan prefijos.

Código fijo:

XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("root", "whatever:name-space-1.0"));
xml.DocumentElement.AppendChild(xml.CreateElement("loner", "whatever:name-space-1.0")); 
Console.WriteLine(xml.OuterXml);

¡Gracias a todos por todas sus respuestas que me llevaron en la dirección correcta!

Otros consejos

Esta es una variante de la respuesta de JeniT (¡Muchas gracias por cierto!)

XmlElement new_element = doc.CreateElement("Foo", doc.DocumentElement.NamespaceURI);

Esto elimina tener que copiar o repetir el espacio de nombres en todas partes.

Si el elemento <loner> en su XML de muestra no tenía la declaración de espacio de nombres predeterminada xmlns, entonces estaría en el espacio de nombres whatever:name-space-1.0 en lugar de no estar en ningún espacio de nombres. Si eso es lo que desea, debe crear el elemento en ese espacio de nombres:

xml.CreateElement("loner", "whatever:name-space-1.0")

Si desea que el elemento <=> no esté en el espacio de nombres, entonces el XML que se ha producido es exactamente lo que necesita, y no debe preocuparse por el atributo <=> que se agrega automáticamente para usted.

Dado que la raíz se encuentra en un espacio de nombres sin prefijar, cualquier hijo de raíz que desee no tener espacios de nombres debe salir como su ejemplo. La solución sería prefijar el elemento raíz de esta manera:

<w:root xmlns:w="whatever:name-space-1.0">
   <loner/>
</w:root>

código:

XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement( "w", "root", "whatever:name-space-1.0" );
doc.AppendChild( root );
root.AppendChild( doc.CreateElement( "loner" ) );
Console.WriteLine(doc.OuterXml);

Si es posible, cree una clase de serialización y luego haga:

XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer serializer = new XmlSerializer(yourType);
serializer.Serialize(xmlTextWriter, someObject, ns);

Es más seguro y puede controlar los espacios de nombres con atributos si realmente necesita más control.

He resuelto el problema usando el patrón de fábrica. Creé una fábrica para objetos XElement. Como parámetro para la creación de instancias de la fábrica, he especificado un objeto XNamespace. Por lo tanto, cada vez que la fábrica crea un XElement, el espacio de nombres se agregará automáticamente. Aquí está el código de la fábrica:

internal class XElementFactory
{
    private readonly XNamespace currentNs;

    public XElementFactory(XNamespace ns)
    {
        this.currentNs = ns;
    }

    internal XElement CreateXElement(String name, params object[] content)
    {
        return new XElement(currentNs + name, content);
    }
}

Sí, puede evitar el XMLNS del elemento Xml. Primero se está creando el tiempo: así

<trkpt lat="30.53597" lon="-97.753324" xmlns="">
    <ele>249.118774</ele>
    <time>2006-05-05T14:34:44Z</time>
</trkpt>

Cambie el código: y pase el espacio de nombres xml como este

Código C #:

XmlElement bookElement = xdoc.CreateElement("trkpt", "http://www.topografix.com/GPX/1/1");
bookElement.SetAttribute("lat", "30.53597");
bookElement.SetAttribute("lon", "97.753324");
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top