C# 如何解析具有混合重复和非重复子节点的节点?

C# 如何解析具有混合重复和非重复子节点的节点?,c#,.net-core,xmlserializer,C#,.net Core,Xmlserializer,让我们从处理任何这样的概念开始,即这可能是一个重复的概念,它只考虑这个结构,可以简单地表示为things:thing[] <things> <thing>..</thing> <thing>..</thing> <thing>..</thing> … </things> .. .. .. … 这个问题是关于如何将以下内容表示为类 <things> <a>

让我们从处理任何这样的概念开始,即这可能是一个重复的概念,它只考虑这个结构,可以简单地表示为
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
XmlSerializer
一起使用

通常我会从类开始,让XmlSerializer告诉我XML格式,但是这个XML是由一个我无法控制的系统定义的

使问题更加复杂的是,string是一个密封的类,因此不能从中继承,因此无法为字段命名而对其进行别名


如何反序列化具有混合重复和非重复子节点的节点?

对我来说,它看起来像是一个不同类型的对象数组,可能继承相同的基类。我会这样做:

[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; }
}

一旦找到它,答案就非常简单:将
xmlement
属性应用于数组成员。详情请参阅

然后,我们可以将零次或多次出现的
d
解析为直接子级,而无需拥有集合节点,并将其键入
对象的数组属性中

为了阐明属性的作用,属性
thing.d
的值是一个集合,其中的元素是匿名的,并且具有类型字符串。序列化正好反映了这一点,为您提供了一个集合节点“d”,其中包含从其类型获取名称的子节点:

<things>
  <a>..</a>
  <b>..</b>
  <c>..</c>
  <d>
    <string>..</string>
    <string>..</string>
    …
  </d>
</things>

..
..
..
..
..
…

然而,这不是我们试图解析的内容。
[xmlement]
属性防止将属性视为集合,如果它不是集合,则它映射到XML的唯一其他方式是作为重复元素

你想在C中得到什么结果?数组a[]、b[]、c[]等,或字典或其他什么?任何东西,@AlexanderPetrov,只要我能解析XML。我不介意围绕数据结构编写代码。序列化时是否应该使用相同的xml?还是序列化不重要?我不是在序列化。我正在使用旧系统的输出打印标签。当我替换更大系统的这一部分时,我可能会使用JSON。我认真考虑过将其标记为可接受的答案。我自己找到了答案,但基里尔在我写结果的过程中发了帖子。我最终选择把我自己的答案标记为正确,因为它既简单又解释性强。Kirill的回答没有说明为什么在
d
上需要
[xmlement]
,也没有解释为什么在非重复元素上不需要它。不过,我感谢他的时间和努力——谢谢你,基里尔。
<things>
  <a>..</a>
  <b>..</b>
  <c>..</c>
  <d>
    <string>..</string>
    <string>..</string>
    …
  </d>
</things>