Pergunta

Eu tenho algum XML que eu desapego em um objeto de negócios. Estou usando o xmlSerializer.DeSerialize para fazê -lo. No entanto, quero que um dos XMLELEMENT contido no XML para manter um Xelement.

Isso não pode ser feito diretamente (usando um XMLELEMEMENTATIBUTIVE), pois o Xelement não é serializável. Eu também tentei serializar esse elemento a uma string (em uma tentativa de duas etapas de obter um Xelement), mas isso falhou com o erro:

Elemento do tipo de nó inesperado. O método ReadeLomentString só pode ser chamado em elementos com conteúdo simples ou vazio

Alguma ideia de como isso pode ser feito?

Aqui está um exemplo de XML e o objeto resultante que eu quero:

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

Objeto:

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

As tentativas que não funcionam:

[XmlElement("Hobbies")]
public XElement Hobbies {get; set;}
[XmlElement("Hobbies")]
public string Hobbies {get; set;}
Foi útil?

Solução

Para evitar o trabalho árduo de implementar algo como IXmlSerializable, você pode fazer algo parecido com um passe semi-oculto XmlElement propriedade; Observe, no entanto, que isso não faz o que você deseja, pois você só pode ter uma raiz XElement valor (não dois, conforme seu exemplo); Você precisaria de uma lista para fazer isso ...

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

Outras dicas

Para ter controle total (juntamente com a responsabilidade total) de como o XML é gerado, você pode que sua classe implemente o System.xml.Serialization.ixmlSerializable Interface e substitua o Readxml e o Writexml. Já tive que fazer isso antes com aulas de dicionário - certifique -se de testar bem, especialmente com propriedades nulas, campos vazios, etc.

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top