Partially deserialize XML to Object

馋奶兔 提交于 2019-12-07 11:58:53

问题


I have some XML that I deserialize into a business object. I am using XmlSerializer.Deserialize to do so. However, I want one of the XmlElement contained in the XML to stay an XElement.

It cannot be done directly (using an XmlElementAttribute) since XElement is not Serializable. I also tried to serialize that element to a string (in a two steps attempt to get an XElement), but that failed with the error:

unexpected node type element. readelementstring method can only be called on elements with simple or empty content

Any idea how that can be done?

Here is an example of xml and the resulting object I want:

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

Object:

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

The attempts that do not work:

[XmlElement("Hobbies")]
public XElement Hobbies {get; set;}
[XmlElement("Hobbies")]
public string Hobbies {get; set;}

回答1:


To avoid the hard work of implementing something like IXmlSerializable, you might do something along the lines of a semi-hidden pass-thru XmlElement property; note, however, that this doesn't quite do what you want since you can only have one root XElement value (not two, as per your example); you would need a list to do that...

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



回答2:


To have full control (along with full responsibility) for how the XML is generated you can have your class implement the System.Xml.Serialization.IXmlSerializable interface, and override ReadXml and WriteXml. I've had to do this before with dictionary classes - be sure to test thoroughly, especially with null properties, empty fields, etc.

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



来源:https://stackoverflow.com/questions/2061981/partially-deserialize-xml-to-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!