Serialización XML: deshabilita la representación del elemento raíz de la matriz


119

¿Puedo de alguna manera desactivar la representación del elemento raíz de la colección?

Esta clase con atributos de serialización:

[XmlRoot(ElementName="SHOPITEM", Namespace="")]
public class ShopItem
{
    [XmlElement("PRODUCTNAME")]
    public string ProductName { get; set; }       

    [XmlArrayItem("VARIANT")]
    public List<ShopItem> Variants { get; set; }
}

genera este XML:

<SHOPITEM xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <PRODUCTNAME>test</PRODUCTNAME>
      <Variants>
          <VARIANT>
              <PRODUCTNAME>hi 1</PRODUCTNAME>
          </VARIANT>
          <VARIANT>
              <PRODUCTNAME>hi 2</PRODUCTNAME>
          </VARIANT>           
      </Variants>        
</SHOPITEM>

No quiero <Variants>elemento aquí. ¿Que debo hacer?

Además, no necesito espacios de nombres xsi y xsd en el elemento raíz ...


Respuestas:


184

Para deshabilitar la representación del elemento raíz de la colección, debe reemplazar el atributo [XmlArrayItem]con [XmlElement]en su código.

Para eliminar los espacios de nombres xsiy xsd, cree una XmlSerializerNamespacesinstancia con un espacio de nombres vacío y páselo cuando necesite serializar su objeto.

Mira este ejemplo:

[XmlRoot("SHOPITEM")]
public class ShopItem
{
    [XmlElement("PRODUCTNAME")]
    public string ProductName { get; set; }

    [XmlElement("VARIANT")] // was [XmlArrayItem]
    public List<ShopItem> Variants { get; set; }
}

// ...

ShopItem item = new ShopItem()
{
    ProductName = "test",
    Variants    = new List<ShopItem>()
    {
        new ShopItem{ ProductName = "hi 1" },
        new ShopItem{ ProductName = "hi 2" }
    }
};

// This will remove the xsi/xsd namespaces from serialization
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");

XmlSerializer ser = new XmlSerializer(typeof(ShopItem));
ser.Serialize(Console.Out, item, ns);  // Inform the XmlSerializerNamespaces here

Tengo esta salida:

<?xml version="1.0" encoding="ibm850"?>
<SHOPITEM>
  <PRODUCTNAME>test</PRODUCTNAME>
  <VARIANT>
    <PRODUCTNAME>hi 1</PRODUCTNAME>
  </VARIANT>
  <VARIANT>
    <PRODUCTNAME>hi 2</PRODUCTNAME>
  </VARIANT>
</SHOPITEM>

Tenga en cuenta que también debe reemplazar [XmlArray]si está presente.
dbc


1

No creo que sea posible eliminar este elemento utilizando la serialización xml predeterminada (con atributos). Si pudiera hacer esto, la serialización de su ShopItemclase daría como resultado un xml mal formado (sin elemento raíz) para el objeto, lo cual no está permitido.

Sin embargo, lo que puede hacer es implementar manualmente IXmlSerializable. Esto le dará el tipo de control detallado que busca.

[ Editar ] - lo siento - malinterpretó que intentaba eliminar Variantes, no SHOPITEM. Para eliminar el elemento "externo" de la lista, márquelo con un atributo [XmlElement] en lugar de un atributo [XmlArrayItem]. Esto hará que las entradas de la lista solo usen el nombre del elemento especificado, sin envolver la lista en un elemento externo.

Para eliminar los espacios de nombres, esto lo controla el propio seriliazer, no el marcado en la clase. Acabo de notar que aunque actualicé esta respuesta, Rubens Farias proporcionó una respuesta que le muestra cómo eliminar el espacio de nombres.


Vaya, leyó mal su publicación, pensó que estaba tratando de eliminar SHOPITEM, ¡solo editando la respuesta!
Rob Levine
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.