使用XML序列化序列化接口列表 [英] Serialize list of interfaces using XML Serialization

查看:149
本文介绍了使用XML序列化序列化接口列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下面的类,我需要使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆