使用XML序列化序列化接口列表 [英] Serialize list of interfaces using XML Serialization
问题描述
我有下面的类,我需要使用XML Serializer序列化
I have the class below which I need to serialize using the XML Serializer
我知道XML序列化器不喜欢接口
I know that the XML serializer does not like interfaces
然而,我们的编码标准通常涉及总是编码到接口而不是具体类
However, our coding standards normally involve always coding to interfaces not concrete classes
我想到了一种能够在不改变的情况下流式传输此列表的方法导致许多编译问题的类型,以及打破我们的标准
I thought of a way to be able to stream this list without changing the types which would cause many compilation issues, as well as breaking our standards
我的想法是有一个属性,它读取Meters列表并转换为具体类然后完全在序列化时忽略米
My idea is to have a property which reads the Meters list and casts to concrete classes then to totally ignore meters when it comes to serializing
但是,XML仍然需要将Meters作为元素名称
However, the XML will still need to have Meters as the element name
但是这不起作用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Xml.Serialization;
public class MeterWalkOrder
{
public MeterWalkOrder()
{
Meters = new List<IMeter>();
}
public String Name { get; set; }
[XmlIgnore]
public List<IMeter> Meters { get; set; }
[XmlArrayItem(ElementName = "Meter")]
[XmlElement(ElementName = "Meters")]
public List<Meter> SerializableMeters
{
get
{
return Meters.Cast<Meter>().ToList();
}
set
{
Meters = new List<IMeter>(value);
}
}
}
}
是有什么方法吗?
我的XML(无法更改)低于
My XML (which cannot be changed) is below
<MeterWalkOrder>
<Name>Red Route</Name>
<Meters>
<Meter>
<MeterID>1</MeterID>
<SerialNumber>12345</SerialNumber>
</Meter>
<Meter>
<MeterID>2</MeterID>
<SerialNumber>SE</SerialNumber>
</Meter>
</Meters>
</MeterWalkOrder>
顶级错误是
那里是反映类型'WindowsFormsApplication1.Classes.MeterWalkOrder'的错误。
There was an error reflecting type 'WindowsFormsApplication1.Classes.MeterWalkOrder'.
内部异常是
{XmlElement ,XmlText和XmlAnyElement不能与XmlAttribute,XmlAnyAttribute,XmlArray或XmlArrayItem一起使用。}
{"XmlElement, XmlText, and XmlAnyElement cannot be used in conjunction with XmlAttribute, XmlAnyAttribute, XmlArray, or XmlArrayItem."}
我真的想避免设置使用列表的先例具体类
I really would like to avoid setting a precedent for using lists of concrete classes
推荐答案
您将需要替换 [XmlElement(ElementName =Meters)]
带 [XmlArray(ElementName =Meters)]
,因错误说明:
You will need to replace [XmlElement(ElementName = "Meters")]
with [XmlArray(ElementName = "Meters")]
as the error states:
{"XmlElement, XmlText, and XmlAnyElement cannot be used in conjunction with XmlAttribute, XmlAnyAttribute, XmlArray, or XmlArrayItem."}
要为 XmlSerializer
定义一个数组,你可以用 XmlArray
及其与 X相对应的项目mlArrayItem
To define an Array for the XmlSerializer
you can mark it with XmlArray
and its corresponding items with XmlArrayItem
示例:
public class MeterWalkOrder
{
public MeterWalkOrder()
{
Meters = new List<IMeter>();
}
public String Name { get; set; }
[XmlIgnore]
public List<IMeter> Meters { get; set; }
[XmlArrayItem(ElementName = "Meter")]
[XmlArray(ElementName = "Meters")]
public List<Meter> SerializableMeters
{
get
{
return Meters.Cast<Meter>().ToList();
}
set
{
Meters = new List<IMeter>(value);
}
}
}
public interface IMeter {
int MeterID { get; set; }
}
public class Meter : IMeter {
public int MeterID { get; set; }
public string SerialNumber { get; set; }
}
测试:
var data = new MeterWalkOrder{ Name = "Red Route", Meters = new List<IMeter>
{
new Meter{ MeterID = 1, SerialNumber = "12345"},
new Meter{ MeterID = 2, SerialNumber = "SE"}
}};
using (var stream = new FileStream("C:\\Users\\Adam\\Desktop\\Test2.xml", FileMode.OpenOrCreate))
{
XmlSerializer ser = new XmlSerializer(typeof(MeterWalkOrder));
ser.Serialize(stream, data);
}
结果:
<?xml version="1.0"?>
<MeterWalkOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Red Route</Name>
<Meters>
<Meter>
<MeterID>1</MeterID>
<SerialNumber>12345</SerialNumber>
</Meter>
<Meter>
<MeterID>2</MeterID>
<SerialNumber>SE</SerialNumber>
</Meter>
</Meters>
</MeterWalkOrder>
这篇关于使用XML序列化序列化接口列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!