繁体   English   中英

如何使用XmlInclude序列化IEnumerable

[英]How to use XmlInclude to serialize IEnumerable

使用XmlSerializer序列化IEnumerable时遇到了问题。 由于IEnumerable表示object列表,因此XmlSerializer不知道需要序列化什么类型。 但是因为需要知道,所以在遇到object以外的其他类型时会抛出InvalidOperationException

类型Foo.Bar不可预期。 使用XmlInclude或SoapInclude属性可以指定静态未知的类型。

XmlIncludeAttribute旨在应用于一种方法,以指示返回值可以是某种类型。 但是, IEnumerable没有可以将属性放在上面的方法。

我尝试将它们应用于GetEnumerator

public class Bar : IEnumerable
{
    private List<object> list;

    public Bar()
    {
    }

    [XmlInclude(typeof(Bar))]
    [XmlInclude(typeof(ChildBar))]
    public IEnumerator GetEnumerator()
    {
        return list.GetEnumerator();
    }

    public void Add(Bar bar)
    {
        list.Add(bar);
    }

    public void Add(ChildBar childBar)
    {
        list.Add(childBar);
    }

    // used for deserialization
    public void Add(object o)
    {
        if (o is Bar || o is ChildBar)
        {
            list.Add(o);
        }
    }

    // more irrelevant stuff
}

public class ChildBar
{
    public ChildBar()
    {
    }

    // more irrelevant stuff
}

那并不能解决问题,我也不知道该在哪里使用这些属性。

我应该放在哪里? 没有他们,我可以解决它吗? 我可以避免编写自己的枚举器吗?

编辑:由于它们是我先前的回答的几个缺陷-没有包含更多条的条并且不使用xmlAttributes,这是我的新解决方案:但是,这没有实现...

编辑:好吧,我回去回顾了一些事情,这是实现ICollection的最终解决方案,希望这对尝试找到序列化Collections的解决方案的所有人有所帮助。

public class Program
{
    static void Main(string[] args)
    {
        var program = new Program();

        program.SerializeObject();
    }

    private int tierIndex = 1;

    public void SerializeObject()
    {
        var barCollection = new BarCollection();
            var bar1 = new Bar() { Name = "bar1" };
            barCollection.Add(bar1);
            var bar2 = new Bar() { Name = "bar2" };
            barCollection.Add(bar2);
                var bar3 = new Bar() { Name = "bar3" };
                bar2.BarCollection.Add(bar3);
                var bar4 = new Bar() { Name = "bar4" };
                bar2.BarCollection.Add(bar4);
            var bar5 = new Bar() { Name = "bar 5" };
            barCollection.Add(bar5);
            var bar6 = new Bar() { Name = "bar 6" };
            barCollection.Add(bar6);
                var bar7 = new Bar() { Name = "bar 7" };
                bar6.BarCollection.Add(bar7);
                    var bar8 = new Bar() { Name = "bar 8" };
                    bar7.BarCollection.Add(bar8);



        var x = new XmlSerializer(typeof(BarCollection));
        x.Serialize(Console.Out, barCollection);

        Console.WriteLine("\n");

        WriteCollection(barCollection);

        Console.ReadLine();
    }

    public void WriteCollection(BarCollection barCollection)
    {
        tierIndex++;

        foreach (Bar bar in barCollection)
        {
            Console.Write(new StringBuilder().Insert(0, "--", tierIndex) + "> ");
            Console.Write(bar.Name + "\n");

            WriteCollection(bar.BarCollection);
        }

        tierIndex--;
    }
}

public class BarCollection : ICollection
{
    private readonly ArrayList barNodes = new ArrayList();

    public Bar this[int index]
    {
        get { return (Bar) barNodes[index]; }
    }

    public void CopyTo(Array a, int index)
    {
        barNodes.CopyTo(a, index);
    }

    public int Count
    {
        get { return barNodes.Count; }
    }

    public object SyncRoot
    {
        get { return this; }
    }

    public bool IsSynchronized
    {
        get { return false; }
    }

    public IEnumerator GetEnumerator()
    {
        return barNodes.GetEnumerator();
    }

    public void Add(Bar bar)
    {
        barNodes.Add(bar);
    }

    public void Add(Object bar)
    {
        barNodes.Add((Bar) bar);
    }
}

public class Bar
{
    [XmlAttribute(AttributeName = "Name")]
    public string Name;

    [XmlArray(ElementName = "BarNodes", IsNullable = true)]
    public BarCollection BarCollection = new BarCollection();
}

继承人的输出:

<?xml version="1.0" encoding="IBM437"?>
<ArrayOfBar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <Bar Name="bar1">
    <BarNodes />
  </Bar>

  <Bar Name="bar2">
    <BarNodes>
      <Bar Name="bar3">
        <BarNodes />
      </Bar>

      <Bar Name="bar4">
        <BarNodes />
      </Bar>

    </BarNodes>
  </Bar>

  <Bar Name="bar 5">
    <BarNodes />
  </Bar>

  <Bar Name="bar 6">
    <BarNodes>
      <Bar Name="bar 7">
        <BarNodes>
          <Bar Name="bar 8">
            <BarNodes />
          </Bar>

        </BarNodes>
      </Bar>

    </BarNodes>
  </Bar>

</ArrayOfBar>

----> bar1
----> bar2
------> bar3
------> bar4
----> bar 5
----> bar 6
------> bar 7
--------> bar 8

另一个堆栈参考: XmlSerializer不会序列化IEnumerable

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM