Serializacja XML - Wyłącz renderowanie głównego elementu tablicy

119

Czy mogę jakoś wyłączyć renderowanie głównego elementu kolekcji?

Ta klasa z atrybutami serializacji:

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

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

generuje ten 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>

Nie chcę <Variants>tutaj elementu. Co muszę zrobić?

Nie potrzebuję też przestrzeni nazw xsi i xsd w elemencie głównym ...

Jan Remunda
źródło

Odpowiedzi:

184

Aby wyłączyć renderowania elementu głównego zbioru, należy wymienić atrybut [XmlArrayItem]ze [XmlElement]w kodzie.

Aby usunąć przestrzenie nazw xsii xsd, utwórz XmlSerializerNamespaceswystąpienie z pustą przestrzenią nazw i przekaż je, gdy musisz serializować obiekt.

Spójrz na ten przykład:

[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

Mam to wyjście:

<?xml version="1.0" encoding="ibm850"?>
<SHOPITEM>
  <PRODUCTNAME>test</PRODUCTNAME>
  <VARIANT>
    <PRODUCTNAME>hi 1</PRODUCTNAME>
  </VARIANT>
  <VARIANT>
    <PRODUCTNAME>hi 2</PRODUCTNAME>
  </VARIANT>
</SHOPITEM>
Rubens Farias
źródło
Pamiętaj, że musisz również wymienić, [XmlArray]jeśli jest obecny.
dbc
32

Wymień [XmlArrayItem("VARIANT")]się [XmlElement("VARIANT")].

Pent Ploompuu
źródło
1

Nie sądzę, aby można było usunąć ten element przy użyciu domyślnej serializacji XML (z atrybutami). Gdybyś mógł to zrobić, serializacja ShopItemklasy spowodowałaby źle sformułowany kod XML (brak elementu głównego) dla obiektu, co jest niedozwolone.

Możesz jednak zrobić to ręcznie IXmlSerializable. To da ci precyzyjną kontrolę, której szukasz.

[ Edytuj ] - przepraszam - źle odczytałeś, że próbujesz usunąć warianty, a nie SHOPITEM. Aby usunąć element „zewnętrzny” listy, wystarczy oznaczyć go atrybutem [XmlElement], a nie atrybutem [XmlArrayItem]. Spowoduje to, że wpisy listy będą używać tylko określonej nazwy elementu, bez zawijania listy zewnętrznym elementem.

Aby usunąć przestrzenie nazw, jest to kontrolowane przez sam seriliazer, a nie przez znaczniki w klasie. Właśnie zauważyłem, że kiedy zaktualizowałem tę odpowiedź, Rubens Farias dostarczył odpowiedź, która pokazuje, jak wyeliminować przestrzeń nazw.

Rob Levine
źródło
Ups - błędnie odczytałem swój post - myślę, że próbujesz usunąć SHOPITEM - po prostu edytujesz odpowiedź!
Rob Levine,