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 ...


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>

Pamiętaj, że musisz również wymienić, [XmlArray]jeśli jest obecny.
dbc


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.


Ups - błędnie odczytałem swój post - myślę, że próbujesz usunąć SHOPITEM - po prostu edytujesz odpowiedź!
Rob Levine,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.