反序列化一个对象中的多个 XML 元素

Posted

技术标签:

【中文标题】反序列化一个对象中的多个 XML 元素【英文标题】:Deserialize multiple XML elements in one object 【发布时间】:2020-07-26 23:02:18 【问题描述】:

我正在使用 XmlSeriazlier 反序列化 xml 文件。

var serializer = new XmlSerializer(typeof(T));
using (var reader = document.CreateReader())
   var result = (T)serializer.Deserialize(reader);

Xml 包含 if/else if/else 条件,需要一起存储在一个对象中。

示例 Xml

<Layers>
  <If if="something" >
    <Layer name="something" />
  </If>
  <ElseIf if="anything" >
    <Layer name="anything" />
  </ElseIf>
  <Else>
    <Layer name="nothing" />
  </Else>

  <If if="something" >
    <Layer name="something" />
  </If>
  <ElseIf if="anything" >
    <Layer name="anything" />
  </ElseIf>

  <If if="something" >
    <Layer name="something" />
  </If>
  <Else>
    <Layer name="nothing" />
  </Else>
</Layers>

语法与编程语言相同。我想知道如何将连接的条件存储在一起。

[XmlRoot("Layers")
public class Layers

    // TODO: Parse conditions to this list.
    public List<Condition>  get; set; 


public class Condition

    public If IfCondition  get; set; 
    public List<IfElse> IfElseConditions  get; set; 
    public Else ElseCondition  get; set; 

【问题讨论】:

【参考方案1】:

xml 模式的选择存在一些重大问题,这使得它对于XmlSerializer 来说并不是一个真正的好选择。具体来说,没有名义上的&lt;Condition&gt;(或类似的),这意味着从序列化程序的角度没有任何东西可以对这些条件进行分组。要捕获数据,您需要:

[XmlRoot("Layers")
public class Layers

    [XmlElement("If")]
    public List<If>  get; set;  // you may be able to share the inner type here
    [XmlElement("ElseIf")]
    public List<ElseIf>  get; set; 
    [XmlElement("Else")]
    public List<Else>  get; set; 

但现在你不知道哪些 if 元素与哪些 else-if 元素搭配,以及与哪些 else 元素搭配。

我怀疑您必须手动实现这一点,在节点类型之间更改时添加您自己的逻辑,但这并非易事。坦率地说,如果可能的话,重新考虑 xml 布局可能会更容易!例如:

<Layers>
  <Condition><!-- some kind of "first match wins" grouping -->
    <Match if="something">
        <Layer name="something" />
    </Match>
    <Match if="anything"><!-- note no need for different if/elseif -->
        <Layer name="anything" />
    </Match>
    <Match> <!-- no "if": acts as wildcard, i.e. "else" -->
        <Layer name="nothing" />
    </Match>
  </Condition>
  <!-- etc -->
</Layers>

【讨论】:

以上是关于反序列化一个对象中的多个 XML 元素的主要内容,如果未能解决你的问题,请参考以下文章

C#中通过XmlSerializer类反序列化多个同名XML元素

Xml 反序列化 - 将两个元素合并到一个 List<T> 对象中

在C#中序列化和反序列化之间保留xml元素的顺序

xStream 问题 - 如何反序列化多个对象

当元素可能是许多可能元素之一时,将 XML 元素反序列化为对象

Xml 反序列化到对象,反射到类型