2010-01-14 140 views
3

我有一些XML反序列化为业务对象。我正在使用XmlSerializer.Deserialize来这样做。但是,我希望XML中包含的一个XmlElement保留XElement。部分反序列化XML到对象

它不能直接(使用XmlElementAttribute),因为的XElement无法序列化完成。我也试着该元素序列化到一个字符串(在两个步骤试图得到的XElement),但失败,错误:

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

不知道如何可以做?

这里是XML的例子并将生成的目标我想:

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

对象:

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

不工作的尝试:

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

回答

3

为了避免执行类似IXmlSerializable的辛勤工作,你可能做一些半隐藏的通行证XmlElement属性;但是,请注意,由于您只能拥有一个根XElement值(不是两个,如您的示例所示),所以这并不完全符合您的要求。你需要一个清单来做到这一点......

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

非常好。我不明白为什么在将XmlElementAttribute指定为'Hobbies'时需要内部节点。然而,我控制了XML,所以我只是在'Hobbies'节点周围添加了一个包装节点,以获得我需要的内容(而不是使用列表)。非常感谢。 – joerage 2010-01-14 15:51:15

1

要取得完整控制(以及全部责任)如何生成XML,您可以让您的类实现System.Xml.S erialization.IXmlSerializable接口,并重写ReadXml和WriteXml。我已经与字典上课前要做到这一点 - 一定要彻底的测试,尤其是空的属性,空字段等

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