我有一些XML,我将其反序列化为业务对象。我正在使用XmlSerializer.Deserialize这样做。但是,我希望XML中包含的一个XmlElement保留一个XElement。
不能直接完成(使用XmlElementAttribute),因为XElement不是Serializable。我还尝试将该元素序列化为一个字符串(两步尝试获取一个XElement),但失败并出现错误:
意外的节点类型元素。 readelementstring方法只能是 用简单或者调用元素 空的内容
知道如何做到这一点?
以下是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;}
答案 0 :(得分:3)
为了避免像IXmlSerializable
这样的实现工作的艰苦工作,你可能会做一些半隐藏的pass-thru 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);
}
}
答案 1 :(得分:1)
要对XML的生成方式进行完全控制(以及完全责任),您可以让您的类实现System.Xml.Serialization.IXmlSerializable接口,并覆盖ReadXml和WriteXml。我必须在使用字典类之前执行此操作 - 确保彻底测试,尤其是使用null属性,空字段等。