Sérialisation XML - Désactiver le rendu de l'élément racine du tableau

119

Puis-je en quelque sorte désactiver le rendu de l'élément racine de la collection?

Cette classe avec des attributs de sérialisation:

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

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

génère ce 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>

Je ne veux pas d' <Variants>élément ici. Que dois-je faire?

De plus, je n'ai pas besoin d'espaces de noms xsi et xsd dans l'élément racine ...

Jan Remunda
la source

Réponses:

184

Pour désactiver le rendu de l'élément racine de la collection, vous devez remplacer l'attribut [XmlArrayItem]par [XmlElement]dans votre code.

Pour supprimer les espaces de noms xsiet xsd, créez une XmlSerializerNamespacesinstance avec un espace de noms vide et transmettez-la lorsque vous devez sérialiser votre objet.

Jetez un œil à cet exemple:

[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

J'ai eu cette sortie:

<?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
la source
Notez que vous devez également le remplacer [XmlArray]s'il est présent.
dbc le
32

Remplacez [XmlArrayItem("VARIANT")]par [XmlElement("VARIANT")].

Pent Ploompuu
la source
1

Je ne pense pas qu'il soit possible de supprimer cet élément en utilisant la sérialisation xml par défaut (avec des attributs). Si vous pouviez faire cela, sérialiser votreShopItem classe entraînerait un XML mal formé (pas d'élément racine) pour l'objet, ce qui n'est pas autorisé.

Ce que vous pouvez faire cependant, c'est mettre en œuvre manuellement IXmlSerializable. Cela vous donnera le genre de contrôle précis que vous recherchez.

[ Modifier ] - désolé - vous avez mal lu que vous essayiez de supprimer des variantes, pas SHOPITEM. Pour supprimer l'élément "externe" de la liste, marquez-le simplement avec un attribut [XmlElement] plutôt qu'avec un attribut [XmlArrayItem]. Cela entraînera que les entrées de la liste utilisent simplement le nom d'élément spécifié, sans envelopper la liste dans un élément externe.

Pour supprimer les espaces de noms, ceci est contrôlé par le seriliazer lui-même, et non par le balisage de la classe. Je viens de remarquer que pendant que j'ai mis à jour cette réponse, Rubens Farias a fourni une réponse qui vous montre comment éliminer l'espace de noms.

Rob Levine
la source
oups - vous avez mal lu votre message - vous pensiez essayer de supprimer SHOPITEM - il vous suffit de modifier la réponse!
Rob Levine