Domanda

Ho qualche XML che ho deserializzare in un oggetto di business. Sto usando XmlSerializer.Deserialize a farlo. Tuttavia, voglio uno dei XmlElement contenuta nel XML di stare una XElement.

Non può essere fatto direttamente (utilizzando un XmlElementAttribute) poiché XElement non è Serializable. Ho anche provato a serializzare quell'elemento in una stringa (in due fasi tentano di ottenere un XElement), ma che non è riuscita con l'errore:

  

inaspettato tipo nodo elemento.   Metodo readelementstring può essere solo   invitato elementi con semplice o   contenuto vuoto

Qualsiasi idea di come si può fare?

Ecco un esempio di XML e l'oggetto risultante voglio:

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

Oggetto:

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

I tentativi che non funzionano:

[XmlElement("Hobbies")]
public XElement Hobbies {get; set;}
[XmlElement("Hobbies")]
public string Hobbies {get; set;}
È stato utile?

Soluzione

Per evitare il duro lavoro di attuare qualcosa di simile IXmlSerializable, si potrebbe fare qualcosa sulla falsariga di un semi-nascosta pass-thru proprietà XmlElement; notare, tuttavia, che questo non abbastanza fare quello che vuoi perché si può avere un solo valore XElement root (non due, secondo il vostro esempio); si avrebbe bisogno di una lista di farlo ...

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);
    }
}

Altri suggerimenti

Per avere il pieno controllo (insieme con piena responsabilità) per come l'XML è generato si può avere la classe implementi l'interfaccia System.Xml.Serialization.IXmlSerializable, e ignorare ReadXml e WriteXml. Ho avuto a che fare prima con le classi del dizionario - essere sicuri di testare a fondo, in particolare con le proprietà null, campi vuoti, etc

.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top