如果我有一个标记为DataContract
的类,并且有一些标有DataMember
属性的属性,我可以轻松地将其序列化为XML,但它会创建如下输出:
<Person>
<Name>John Smith</Name>
<Email>john.smith@acme.com</Email>
<Phone>123-123-1234</Phone>
</Person>
我更喜欢的是属性,比如......
<Person Name="John Smith" Email="john.smith@acme.com" Phone="123-123-1234" />
DataMember
属性允许我控制名称和顺序,但不能控制它是否被序列化为元素或属性。我环顾四周找到DataContractFormat
和IXmlSerializable
,但我希望有更简单的解决方案。
最简单的方法是什么?
答案 0 :(得分:37)
你可以用 DataContractSerializer - 答案是 接管Xml序列化 你自己实施的 IXmlSerializable接口。对于 只写支持 - 你可以离开 ReadXml的实现为空,和 为GetSchema返回null,然后 编写WriteXml的实现 如下:
public class MyPerson : IXmlSerializable
{
public string Name { get; set;}
public string Email { get; set;}
public string Phone { get; set;}
public XmlSchema GetSchema() { return null; }
public void ReadXml(XmlReader reader) { }
public void WriteXml(XmlWriter writer)
{
writer.WriteAttributeString("name", Name);
writer.WriteAttributeString("email", Email);
writer.WriteAttributeString("phone", Phone);
}
}
如果你也使用相同的类型,比如JSON序列化,那么你仍然可以自由添加DataContract和DataMember属性 - 只有在编写Xml时,DataContractSerializer才会使用IXmlSerializable接口实现。
我在博客上发表了这篇文章here。
答案 1 :(得分:13)
您不能使用DataContractSerializer
执行此操作;如果您需要属性,则需要使用XmlSerializer
。对于DataContractSerializer
类,允许使用更严格的XML规范子集,这样可以提高性能,并提高已发布服务的互操作性,但是对XML格式的控制较少。
如果您正在使用WCF服务,请查看XmlSerializerFormatAttribute
,以便您使用XmlSerializer
进行序列化。
答案 2 :(得分:0)
序列化/反序列化时,您可以在属性和元素之间来回转换。以下适用于后者。
private XmlReader AttributesToElements( Stream stream )
{
var root = XElement.Load( stream );
foreach ( var element in root.Descendants() ) {
foreach ( var attribute in element.Attributes() )
element.Add( new XElement( root.Name.Namespace + attribute.Name.LocalName, (string)attribute ) );
element.Attributes().Remove();
}
return root.CreateReader();
}