XmlIninclude :列表和数组
我有一个对象,其变量为 object
,我想在 XML 中序列化它。
为此,我添加了一些 XmlInclude
属性,以便管理所有可以使用的类型。
[Serializable]
[XmlInclude(typeof(short[]))]
[XmlInclude(typeof(ushort[]))]
[XmlInclude(typeof(int[]))]
[XmlInclude(typeof(uint[]))]
[XmlInclude(typeof(ulong[]))]
[XmlInclude(typeof(long[]))]
[XmlInclude(typeof(byte[]))]
[XmlInclude(typeof(decimal[]))]
[XmlInclude(typeof(float[]))]
[XmlInclude(typeof(double[]))]
[XmlInclude(typeof(string[]))]
[XmlInclude(typeof(List<short>))]
[XmlInclude(typeof(List<ushort>))]
[XmlInclude(typeof(List<int>))]
[XmlInclude(typeof(List<uint>))]
[XmlInclude(typeof(List<long>))]
[XmlInclude(typeof(List<ulong>))]
[XmlInclude(typeof(List<byte>))]
[XmlInclude(typeof(List<decimal>))]
[XmlInclude(typeof(List<float>))]
[XmlInclude(typeof(List<double>))]
[XmlInclude(typeof(List<string>))]
[XmlInclude(typeof(MyObject))]
[XmlInclude(typeof(TimeSpan))]
[XmlInclude(typeof(OtherObject))]
[XmlInclude(typeof(MySubObject1))]
[XmlInclude(typeof(MySubObject2))]
[XmlRoot(ElementName = "mc")]
public class MyClass: IComparable
{
[XmlElement("fm")]
public object FirstMember;
[XmlElement("sm")]
public object SecondMember;
[XmlElement("tm")]
public object ThirdMember;
}
我的问题是数组和列表声明不共存。
奇怪的是,如果将数组属性放在前面,则数组成员会被正确序列化,但列表成员不会被正确序列化。反之亦然。
自定义类和派生类可以正常工作,但 List
和 Array
则不行。我只能找到类的示例,但我使用原始类型。
有人有主意吗?
PS:我知道我的帖子类似于 这个,但自 2011 年以来一直没有答案。
I have an object that have variables as object
, and I want to serialize it in XML.
To do so, I've added some XmlInclude
attributes in order to manage all the types that can be used.
[Serializable]
[XmlInclude(typeof(short[]))]
[XmlInclude(typeof(ushort[]))]
[XmlInclude(typeof(int[]))]
[XmlInclude(typeof(uint[]))]
[XmlInclude(typeof(ulong[]))]
[XmlInclude(typeof(long[]))]
[XmlInclude(typeof(byte[]))]
[XmlInclude(typeof(decimal[]))]
[XmlInclude(typeof(float[]))]
[XmlInclude(typeof(double[]))]
[XmlInclude(typeof(string[]))]
[XmlInclude(typeof(List<short>))]
[XmlInclude(typeof(List<ushort>))]
[XmlInclude(typeof(List<int>))]
[XmlInclude(typeof(List<uint>))]
[XmlInclude(typeof(List<long>))]
[XmlInclude(typeof(List<ulong>))]
[XmlInclude(typeof(List<byte>))]
[XmlInclude(typeof(List<decimal>))]
[XmlInclude(typeof(List<float>))]
[XmlInclude(typeof(List<double>))]
[XmlInclude(typeof(List<string>))]
[XmlInclude(typeof(MyObject))]
[XmlInclude(typeof(TimeSpan))]
[XmlInclude(typeof(OtherObject))]
[XmlInclude(typeof(MySubObject1))]
[XmlInclude(typeof(MySubObject2))]
[XmlRoot(ElementName = "mc")]
public class MyClass: IComparable
{
[XmlElement("fm")]
public object FirstMember;
[XmlElement("sm")]
public object SecondMember;
[XmlElement("tm")]
public object ThirdMember;
}
My issue is that array and list declarations don't coexist.
And weird thing, if the array attributes are placed first, the array members are correctly serialized, but not the list ones. And vice-versa.
The custom classes and derived ones work fine, but List
and Array
don't. I can only find example with classes, but I use primitive types.
Does anyone have an idea ?
P.S.: I know that my post is similar of this one, but it has no answer since 2011.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我可以重现该问题。发生这种情况是因为
XmlSerializer
为数组和列表(在本例中为字符串)生成相同的 XML:由于序列化程序使用相同的
xsi:type
多态名称,"ArrayOfString"
,对于string[]
和List
,当它发现可能遇到两者的情况时,它抛出一个例外,因为它无法区分它们。为什么
XmlSerializer
两者使用相同的名称?我只能猜测它可以交换通过序列化不同集合类型(例如从List
到SortedSet
)创建的 XML,而无需修复XML 文件格式。但是,就您的情况而言,您需要在 XML 中区分这些类型的集合,而不是互换它们。因此,您将需要创建某种包装类,以允许在文件中区分它们。
例如,请考虑对您的类进行以下简化:
这里
FirstMember
可以包含一个字符串、一个字符串或对象数组,或者各种类型的字符串或对象集合。要为各种类型的集合建立不同的
xsi:type
值,可以引入以下通用包装类型:然后在简化的类中使用,如下所示:
然后,对于简单的字符串列表:
以下生成 XML:
如您所见,
xsi:type
现在是不同的。如果我创建以下更复杂的对象:
将生成以下 XML:
每种不同的集合类型都有其独特的
xsi:type
。I can reproduce the problem. It happens because
XmlSerializer
generates the same XML for both an array and a list (of strings, in this case):Since the serializer uses the same
xsi:type
polymorphic name,"ArrayOfString"
, for bothstring[]
andList<string>
, when it finds a situation where both might be encountered, it throws an exception, since it cannot distinguish between them.Why does does
XmlSerializer
use the same name for both? I can only guess that it enables interchanging XML created by serializing different collection types (fromList<TElement>
toSortedSet<TElement>
, for instance) without a need to fix the XML file format.But, in your case, you need to distinguish between these types of collections in XML, rather than interchange them. Thus you are going to need to create some sort of wrapper class that allows them to be distinguished in the file.
For instance, consider the following simplification of your class:
Here
FirstMember
can contain a string, an array of strings or objects, or various types of collection of strings or objects.To establish distinct
xsi:type
values for various types of collection, the following generic wrapper types can be introduced:And then used in your simplified class as follows:
Then, for a simple list of strings:
The following XML is generated:
As you can see, the
xsi:type
is now distinct.And if I create the following more complex object:
The following XML is generated:
Each different collection type how has its own distinct
xsi:type
.