让我们首先处理任何可能与How to read xml document in MVC core (1.0.0)?重复的概念,things: thing[]
只考虑这种结构,简单地表达为<things>
<thing>..</thing>
<thing>..</thing>
<thing>..</thing>
…
</things>
。
<things>
<a>..</a>
<b>..</b>
<c>..</c>
<d>..</d>
<d>..</d>
<d>..</d>
…
</things>
这个问题是关于如何将以下内容表达为类。
IDictionary<T1,T2>
这绝对不是一个数组。它可以说是一本字典,但明确禁止我们使用XmlSerializer
和[XmlInclude(typeof(A))]
[XmlInclude(typeof(B))]
...
public class BaseClass {}
[XmlRoot("a")]
public class A : BaseClass { }
[XmlRoot("b")]
public class B : BaseClass { }
...
public class Things
{
[XmlElement("things")]
public BaseClass[] Items { get; set; }
}
。
通常我会从类开始,让XmlSerializer告诉我XML格式,但这个XML是由我无法控制的系统定义的。
使问题更复杂的是string是一个密封类,因此你无法继承它,因此无法为命名字段而对其进行别名。
如何使用混合重复和非重复子节点反序列化节点?
对我来说,它看起来像一个不同类型的对象数组,可能会继承相同的基类。我会做这样的事情:
XmlElement
一旦找到它,答案就会非常简单:将https://docs.microsoft.com/en-us/dotnet/standard/serialization/controlling-xml-serialization-using-attributes#serializing-an-array-as-a-sequence-of-elements属性应用于数组成员。有关public class thing {
public string a { get; set; }
public string b { get; set; }
public string c { get; set; }
[XmlElement]
public string[] d { get; set; }
}
的更多详情
d
然后,我们可以将thing
的零次或多次出现作为没有集合节点的直接子节点来拥有并键入它们,将它们解析为thing.d
对象上的数组属性。
为了阐明属性的效果,属性<things>
<a>..</a>
<b>..</b>
<c>..</c>
<d>
<string>..</string>
<string>..</string>
…
</d>
</things>
的值是一个集合,其中元素是匿名的并且具有类型字符串。序列化正好反映了这一点,为您提供了一个带有子节点的集合节点“d”,这些节点从其类型中获取其名称:
[XmlElement]
但是,这不是我们要解析的内容。 qazxswpoi属性可以防止将属性视为集合,如果它不是集合,则它可以映射到XML的唯一其他方式是作为重复元素。