串行化没有根元素的集合集合时出现XmlSerializer错误?

时间:2010-01-18 11:38:55

标签: .net collections xmlserializer

这是一个很长的问题,但我尽可能简洁,所以请耐心等待。它看起来像XmlSerializer类中的一个错误,但在我向微软提交之前我想看看是否有任何我错过的,这是完全可能的。

我正在尝试生成以下XML作为代表性案例,它本质上是集合的集合,但外部集合中有其他元素:

<Links>
  <Name />
  <Group>
    <Link />
    <Link />
  </Group>
  <Group>
    <Link />
    <Link />
  </Group>
</Links>

序列化类如下:

public class Link { }

public class Links
{
    public string Name { get; set; }

    [XmlElement("Group")]
    public Link[][] Groups { get; set; }
}

运行它的简单测试程序如下:

class Program
{
    static void Main()
    {
        var serializer = new XmlSerializer(typeof(Links));
        var links = new Links { Name = "", Groups = new[] { 
            new[] { new Link(), new Link() }, 
            new[] { new Link(), new Link() } } };
        serializer.Serialize(Console.Out, links);
    }
}

这采用了using XmlElement to remove the parent node of the collection的技巧,这意味着不会发出<Groups>个元素,并且对于外部数组中包含的每个对象(类型为Link[])a应该发出<Group>个元素。但是,在运行时,这会从XmlSerializer

中提供以下异常
  

无法生成临时类(result = 1)。   错误CS0030:无法将类型'Link [] []'转换为'Link []'   错误CS0029:无法将类型'Link []'隐式转换为'Link [] []'

我的猜测是序列化程序出于某种原因试图压缩集合,并认为外部数组中包含的类型是Link而不是Link[],这导致其序列化的编译失败作为类型的类不匹配。

你怎么看?这是一个错误吗?是否有使用XmlSerializer生成XML的解决方法?

3 个答案:

答案 0 :(得分:1)

我可以使用XmlArrayItem属性获得几乎相同的结构:

[XmlArrayItem(ElementName = "Group", Type = typeof(Link[]))]
Link[][] Groups;

但我仍然得到一个顶级的Groups元素。至少锯齿状阵列的序列化就是这样的。

就我的测试而言,没有办法让XmlElement属性与锯齿状数组一起使用。无论这是一个bug还是一个“功能”,我都不确定。我同意,从错误消息判断,这看起来像一个错误。至少它应该抛出不支持带有锯齿数组属性的XmlElement,而不是在尝试将[]放入[] []时失败。

答案 1 :(得分:1)

我建议编写一个XML模式,它定义了您希望在XML中使用的语法,并使用代码生成工具(例如MS xsd.exe)从中生成相应的序列化代码。 无论如何,编写模式是一种很好的数据验证方法。即使您以后不想使用它而宁愿自己维护代码,也至少可以查看生成的代码。

答案 2 :(得分:0)

对于我所看到的,问题正是错误说的地方。

为您尝试序列化的类编写所需XML的方式,显示Group是Links的集合;但是,它被定义为链接的锯齿状数组(即数组数组)。

我相信你将它恢复为一个简单的数组,问题就会解决。


已编辑添加

如果你真的需要拥有你指定的XML,你可以实现IXmlSerializable接口并自己创建和读取XML。

当事情不按我们预期的方式运作时,它始终是一种解决方案。