Question

J'ai quelques XML que je deserialize dans un objet métier. J'utilise XmlSerializer.Deserialize de le faire. Cependant, je veux un des XmlElement contenues dans le fichier XML pour rester un XElement.

Il ne peut pas être fait directement (en utilisant un XmlElementAttribute) depuis XElement n'est pas Serializable. J'ai aussi essayé de sérialisation cet élément à une chaîne (dans un deux étapes tentent d'obtenir un XElement), mais qui a échoué avec l'erreur:

  

élément de type de nœud inattendu.   méthode readelementstring ne peut être   appelé sur des éléments simples ou avec   contenu vide

Toute idée de comment cela peut être fait?

Voici un exemple de xml et l'objet résultant je veux:

<Person name="Joe">
  <Hobbies>
    <Hobby name="Reading" .../>
    <Hobby name="Photography" .../>
  </Hobbies>
  <HomeAddress>
    ...
  </HomeAddress>
</Person>

Objet:

 public class Person
    {
      [XmlAttribute("Name")]
      public string Name {get; set;}
      ?????
      public XElement Hobbies {get; set;}
      [XmlElement("HomeAddress")]
      public Address HomeAddress {get; set;}
    }

Les tentatives qui ne fonctionnent pas:

[XmlElement("Hobbies")]
public XElement Hobbies {get; set;}
[XmlElement("Hobbies")]
public string Hobbies {get; set;}
Était-ce utile?

La solution

Pour éviter le dur travail de mettre en œuvre quelque chose comme IXmlSerializable, vous pourriez faire quelque chose le long des lignes d'un pass-thru propriété XmlElement semi-cachée; noter, cependant, que cela ne fait pas tout à fait ce que vous voulez puisque vous ne pouvez avoir une racine valeur XElement (pas deux, selon votre exemple); vous auriez besoin d'une liste pour le faire ...

using System;
using System.ComponentModel;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
public class Person
{
    [XmlAttribute("Name")]
    public string Name { get; set; }
    [XmlIgnore]
    public XElement Hobbies { get; set; }

    [XmlElement("Hobbies")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public XmlElement HobbiesSerialized
    {
        get
        {
            XElement hobbies = Hobbies;
            if(hobbies == null) return null;
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(hobbies.ToString());
            return doc.DocumentElement;
        }
        set
        {
            Hobbies = value == null ? null
                : XElement.Parse(value.OuterXml);
        }
    }
    [XmlElement("HomeAddress")]
    public Address HomeAddress { get; set; }
}

public class Address { }

static class Progmam
{
    static void Main()
    {
        var p = new Person { Hobbies = new XElement("xml", new XAttribute("hi","there")) };
        var ser = new XmlSerializer(p.GetType());
        ser.Serialize(Console.Out, p);
    }
}

Autres conseils

Pour avoir le plein contrôle (ainsi que la pleine responsabilité) de la façon dont le XML est généré, vous pouvez avoir votre classe implémente l'interface System.Xml.Serialization.IXmlSerializable, et passer outre ReadXml et WriteXml. J'ai dû le faire avant avec des classes de dictionnaire - assurez-vous de bien tester, en particulier avec des propriétés null, les champs vides, etc

.

http://www.devx.com/dotnet/Article/29720

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top