这是一个很长的问题,但我尽可能简洁,所以请耐心等待。它看起来像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的解决方法?
答案 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。
当事情不按我们预期的方式运作时,它始终是一种解决方案。