如何将不同名称的 XML 节点反序列化为相同的基本类型

Posted

技术标签:

【中文标题】如何将不同名称的 XML 节点反序列化为相同的基本类型【英文标题】:How to Deseralize XML nodes of different names to same base type 【发布时间】:2020-12-08 07:54:36 【问题描述】:

我在网上找不到一个示例,该示例准确地解释了如何配置 XmlSerializer 以按照我想要的方式反序列化 XML。

我想将此 XML 反序列化为 Fruits 或至少是 List<Fruit>

<fruits>
  <apple>fruitstuff</apple>
  <orange>fruitstuff</orange>
  <pear>fruitstuff</pear>
<fruits>

我想象一个看起来像这样的模型

class Fruits : List<Fruit> 

class Fruit 
  fruitstuff


class Apple : Fruit 

class Orange : Fruit 

class Pear : Fruit 

我遇到的问题是 XmlSerlization 配置和 XML 属性的某种组合。当我提供 XmlSeralizer 时,可以读取 XML 而不会引发错误,但是它不能识别水果的集合。该集合将包含零个元素。

var seralizer = new XmlSerializer(typeof(Fruits), new XmlRootAttribute("Fruits"));

我对互联网的问题是,如何配置序列化程序以识别类似节点并将其反序列化为基本类型的集合?

我宁愿有一个精心配置的自定义序列化程序而不是 XmlAttributed 模型。我可能想使用除 XML 之外的其他格式的模型。我认为在我的模型中使用 xml 属性不如有针对性的序列化实现那么优雅。

【问题讨论】:

【参考方案1】:
    添加&lt;fruit&gt;元素以包装多个&lt;fruits&gt;元素 将XmlRootXmlElement 属性添加到相应的类中。

我的示例代码和它的工作原理:

class Program


    static void Main(string[] args)
    
        string xml = @"
        <fruit>
            <fruits>
              <apple>
                 <attr1>1</attr1>
                 <attr2>2</attr2>
              </apple>
              <orange>
                 <attr1>3</attr1>
                 <attr2>4</attr2>
              </orange>
              <pear>
                 <attr1>5</attr1>
                 <attr2>6</attr2>
              </pear>
            </fruits> 
            <fruits>
              <apple>
                 <attr1>7</attr1>
                 <attr2>8</attr2>
              </apple>
              <orange>
                 <attr1>9</attr1>
                 <attr2>10</attr2>
              </orange>
              <pear>
                 <attr1>11</attr1>
                 <attr2>12</attr2>
              </pear>
            </fruits>   
        </fruit>
            ";
        var ser = new XmlSerializer(typeof(Fruit));
        using (var reader = new StringReader(xml))
        
            var myFruits = (Fruit)ser.Deserialize(reader);
        

        Console.Read();
    



[XmlRoot("fruit")]
public class Fruit

    [XmlElement("fruits")]
    public List<Fruits> Fruits  get; set; 



public class Fruits

    [XmlElement("apple")]
    public Apple Apple  get; set; 

    [XmlElement("orange")]
    public Orange Orange  get; set; 

    [XmlElement("pear")]
    public Pear Pear  get; set; 


public class FruitCommonProperty

    [XmlElement("attr1")]
    public string Attr1  get; set; 

    [XmlElement("attr2")]
    public string Attr2  get; set; 


public class Apple : FruitCommonProperty  

public class Orange : FruitCommonProperty  

public class Pear : FruitCommonProperty  

【讨论】:

部分问题在于输入 XML 是按原样提供的外部输入。提供的示例是现实世界问题的简化版本。限制之一是 XML 结构不可修改。如果我可以改变 XML 的结构,我会采用完全不同的格式。

以上是关于如何将不同名称的 XML 节点反序列化为相同的基本类型的主要内容,如果未能解决你的问题,请参考以下文章

C# XMLSerializer 将错误的类型反序列化为 List

如何在c#中使用具有相同名称但不同属性和结构的元素反序列化XML

Jackson 反序列化同名的 xml 字段

JAXB - java xml解析

C#将不同类型的xml数组反序列化为多个数组

如何将不同类型的子元素反序列化为基类型的列表/集合,这是相应类的属性