Serializzazione XML: disabilita il rendering dell'elemento radice dell'array


119

Posso in qualche modo disabilitare il rendering dell'elemento radice della raccolta?

Questa classe con attributi di serializzazione:

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

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

genera questo 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>

Non voglio l' <Variants>elemento qui. Cosa devo fare?

Inoltre non ho bisogno degli spazi dei nomi xsi e xsd nell'elemento root ...


Risposte:


184

Per disabilitare il rendering dell'elemento radice della raccolta, è necessario sostituire l'attributo [XmlArrayItem]con [XmlElement]nel codice.

Per rimuovere gli spazi dei nomi xsie xsd, creare XmlSerializerNamespacesun'istanza con uno spazio dei nomi vuoto e passarla quando è necessario serializzare l'oggetto.

Dai un'occhiata a questo esempio:

[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

Ho questo risultato:

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

Nota che devi anche sostituire [XmlArray]se presente.
dbc


1

Non credo sia possibile rimuovere questo elemento utilizzando la serializzazione xml predefinita (con attributi). Se potessi farlo, serializzare la tua ShopItemclasse risulterebbe in xml mal formato (nessun elemento root) per l'oggetto, il che non è consentito.

Quello che puoi fare, tuttavia, è implementarlo manualmente IXmlSerializable. Questo ti darà il tipo di controllo a grana fine che stai cercando.

[ Modifica ] - scusa - ho letto male che stavi cercando di rimuovere le varianti, non SHOPITEM. Per rimuovere l'elemento List "esterno", contrassegnalo con un attributo [XmlElement] anziché con un attributo [XmlArrayItem]. Ciò farà sì che le voci dell'elenco utilizzino solo il nome dell'elemento specificato, senza racchiudere l'elenco in un elemento esterno.

Per la rimozione degli spazi dei nomi, ciò è controllato dal seriliazer stesso, non dal markup della classe. Ho appena notato che mentre aggiornavo questa risposta, Rubens Farias ha fornito una risposta che mostra come eliminare lo spazio dei nomi.


oops - ho letto male il tuo post - pensavo stessi cercando di rimuovere SHOPITEM - ho solo modificato la risposta!
Rob Levine
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.