web-dev-qa-db-fra.com

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

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

111
Jan Remunda

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

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

Jetez un oeil sur 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 obtenu 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>
172
Rubens Farias

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

31
Pent Ploompuu

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

Cependant, vous pouvez implémenter manuellement IXmlSerializable. Cela vous donnera le genre de contrôle fin que vous recherchez.

[ Modifier ] - désolé - a mal lu que vous tentiez de supprimer des variantes, pas SHOPITEM. Pour supprimer l'élément List "externe", il suffit de le marquer avec un attribut [XmlElement] plutôt qu'un attribut [XmlArrayItem]. Cela entraînera les entrées de liste à utiliser simplement le nom d'élément spécifié, sans encapsuler la liste dans un élément externe.

Pour supprimer les espaces de noms, cela 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.

1
Rob Levine