2009-12-30 4 views
2

J'ai une classe dont j'ai besoin pour faire une sortie XML personnalisée, donc j'implémente l'interface IXmlSerializable. Cependant, certains des champs que je veux sortir avec la sérialisation par défaut, sauf que je veux changer les noms de balises xml. Lorsque j'appelle serializer.Serialize, j'obtiens des noms de balises par défaut dans le XML. Est-ce que je peux changer ça?Sérialisation personnalisée à l'aide de XmlSerializer

Voici mon code:

public class myClass: IXmlSerializable 
{ 
    //Some fields here that I do the custom serializing on 
    ... 

    // These fields I want the default serialization on except for tag names 
    public string[] BatchId { get; set; } 
    ... 

    ... ReadXml and GetSchema methods are here ... 

    public void WriteXml(XmlWriter writer) 
    {       
     XmlSerializer serializer = new XmlSerializer(typeof(string[])); 
     serializer.Serialize(writer, BatchId); 
     ... same for the other fields ... 

     // This method does my custom xml stuff 
     writeCustomXml(writer); 
    } 

    // My custom xml method is here and works fine 
    ... 
} 

Voici ma sortie Xml:

<MyClass> 
    <ArrayOfString> 
     <string>2643-15-17</string> 
     <string>2642-15-17</string> 
     ... 
    </ArrayOfString> 
    ... My custom Xml that is correct .. 
    </MyClass> 

Ce que je veux retrouver avec:

<MyClass> 
    <BatchId> 
     <id>2643-15-17</id> 
     <id>2642-15-17</id> 
     ... 
    </BatchId> 
    ... My custom Xml that is correct .. 
    </MyClass> 
+0

Comment souvent vous sérialisation/désérialisation? Des centaines de fois pendant le cycle de vie de l'application ou uniquement au démarrage ou à l'arrêt. Si le premier j'ai une mise en œuvre qui est nettement plus flexible. –

+0

Vraiment seulement la sérialisation une fois. Cette application est un outil simple qui tire des données d'un format de base de données propriétaire et enregistre au format XML. Donc, je suis en train de tirer des données dans un modèle d'objet, puis immédiatement en série. La plupart des données étaient simples, donc je n'ai pas eu besoin d'implémenter IXmlSerializable ... mais cette donnée particulière était un peu pénible. – KrisTrip

+0

Eh bien jetez un oeil ici, le code est MIT http://code.google.com/p/videobrowser/source/browse/MediaBrowser/Library/Persistance/XmlSettings.cs il y a un test unitaire, vous devrez peut-être prolonge un peu, mais toute l'architecture est là. plus pour votre scénario, il sera beaucoup mieux que XmlSerializer –

Répondre

7

Dans de nombreux cas, vous pouvez utiliser le constructeur surcharge XmlSerializer qui accepte un XmlAttributeOverrides pour préciser ces informations de nom supplémentaires (par exemple, en passant une nouvelle XmlRootAttribute) - cependant, cela ne fonctionne pas pour les tableaux AFAIK. Je m'attends à l'exemple string[], il serait plus simple de l'écrire manuellement. Dans la plupart des cas, IXmlSerializable est beaucoup de travail supplémentaire - je l'évite autant que possible pour des raisons comme celle-ci. Pardon.

+0

XmlSerializer est un vieux morceau de technologie non maintenu et inefficace qui aurait dû être obsolète par MS il y a des siècles, ou au strict minimum réimplémenté. J'ai seulement eu des problèmes avec ça. Mieux vaut utiliser les tampons de protocole: p –

+0

Comment est-il tentant de voir si je peux lancer la sortie de pb-net en xml ;-p –

+0

vous devriez totalement le faire, et le rendre pluggable afin que les gens puissent implémenter leur propre format de persistance, puis vous pourriez même utiliser sqlite comme magasin de données ... –

3

Vous pouvez marquer vos champs avec des attributs à control the serialized XML. Par exemple, en ajoutant les attributs suivants:

[XmlArray("BatchId")] 
[XmlArrayItem("id")] 
public string[] BatchId { get; set; } 

va probablement vous y arriver.

+1

essayé. Pas de chance. – KrisTrip

0

Si quelqu'un est toujours à la recherche de cela, vous pouvez certainement utiliser le XmlArrayItem, mais cela doit être une propriété dans une classe. Pour des raisons de lisibilité, vous devez utiliser le pluriel et le singulier du même mot.

/// <summary> 
    /// Gets or sets the groups to which the computer is a member. 
    /// </summary> 
    [XmlArrayItem("Group")] 
    public SerializableStringCollection Groups 
    { 
     get { return _Groups; } 
     set { _Groups = value; } 
    } 
    private SerializableStringCollection _Groups = new SerializableStringCollection(); 



<Groups> 
    <Group>Test</Group> 
    <Group>Test2</Group> 
</Groups> 

David

Questions connexes