如何解析混合重复和非重复子节点的节点?
How to parse nodes with mixed repeating and non-repeating child nodes?
让我们首先处理任何认为这可能是 的副本的想法,它只考虑这个结构,可以简单地表示为 things: thing[]
.
<things>
<thing>..</thing>
<thing>..</thing>
<thing>..</thing>
…
</things>
这道题是关于如何用classes.
<things>
<a>..</a>
<b>..</b>
<c>..</c>
<d>..</d>
<d>..</d>
<d>..</d>
…
</things>
这绝对不是数组。它 是 可以说是一本字典,但我们明确禁止将 IDictionary<T1,T2>
与 XmlSerializer
.
一起使用
通常我会从 classes 开始,让 XmlSerializer 告诉我 XML 格式,但是这个 XML 是由我无法控制的系统定义的。
使问题更加复杂的是字符串是密封的 class,因此您无法从它继承,因此无法为命名字段而对其进行别名。
如何反序列化具有混合重复和非重复子节点的节点?[=16=]
对我来说,它看起来像是一组不同类型的对象,它们可能继承相同的基础 class。我会做这样的事情:
[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; }
}
一旦找到它,答案就简单得令人尴尬:将 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
的值是一个 集合 ,其中的元素是匿名的,类型为字符串.序列化恰好反映了这一点,为您提供了一个集合节点 "d",其子节点的名称来自其类型:
<things>
<a>..</a>
<b>..</b>
<c>..</c>
<d>
<string>..</string>
<string>..</string>
…
</d>
</things>
但是,这不是我们要解析的内容。 [XmlElement]
属性防止 属性 被视为一个集合,如果它不是一个集合,那么它可以映射到 [=31] 的唯一 other 方式=] 作为重复元素。
让我们首先处理任何认为这可能是 things: thing[]
.
<things>
<thing>..</thing>
<thing>..</thing>
<thing>..</thing>
…
</things>
这道题是关于如何用classes.
<things>
<a>..</a>
<b>..</b>
<c>..</c>
<d>..</d>
<d>..</d>
<d>..</d>
…
</things>
这绝对不是数组。它 是 可以说是一本字典,但我们明确禁止将 IDictionary<T1,T2>
与 XmlSerializer
.
通常我会从 classes 开始,让 XmlSerializer 告诉我 XML 格式,但是这个 XML 是由我无法控制的系统定义的。
使问题更加复杂的是字符串是密封的 class,因此您无法从它继承,因此无法为命名字段而对其进行别名。
如何反序列化具有混合重复和非重复子节点的节点?[=16=]
对我来说,它看起来像是一组不同类型的对象,它们可能继承相同的基础 class。我会做这样的事情:
[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; }
}
一旦找到它,答案就简单得令人尴尬:将 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
的值是一个 集合 ,其中的元素是匿名的,类型为字符串.序列化恰好反映了这一点,为您提供了一个集合节点 "d",其子节点的名称来自其类型:
<things>
<a>..</a>
<b>..</b>
<c>..</c>
<d>
<string>..</string>
<string>..</string>
…
</d>
</things>
但是,这不是我们要解析的内容。 [XmlElement]
属性防止 属性 被视为一个集合,如果它不是一个集合,那么它可以映射到 [=31] 的唯一 other 方式=] 作为重复元素。