首页 > 解决方案 > 在 C# 中反序列化具有不同类型名称的 XML 元素

问题描述

我被困在如何解决这个 XML 结构的反序列化问题上。元素“allocatables”在同一个命名空间中有不同的类型。这些元素是否在“employeeAllocation”元素/对象中的一个或多个列表中反序列化并不重要。

这是 XML 片段。

    <ns3:EmployeeAllocationResponse
    xmlns:ns3="http://employeeallocation.intf.mb.ivu.de/"
    xmlns:ns2="http://employeeallocation.intf.mb.ivu.de/fault">
    <employeeAllocation>
        <allocatables
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns3:Duty">
            <startTime>2020-11-03T14:09:00.000</startTime>
            <endTime>2020-11-03T22:50:00.000</endTime>
            <shortName>64280S</shortName>
        </allocatables>
        <allocatables
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns3:Duty">
            <startTime>2020-11-03T14:09:00.000</startTime>
            <endTime>2020-11-03T22:50:00.000</endTime>
            <shortName>64280S</shortName>
        </allocatables>
    </employeeAllocation>
    <employeeAllocation>
        <allocatables
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns3:Absence">
            <typeAbbreviation>STAG</typeAbbreviation>
            <typeLongname>STAG-dagar</typeLongname>
            <startTime>2020-11-03T00:00:00.000</startTime>
            <endTime>2020-11-04T00:00:00.000</endTime>
            <type>STAG</type>
        </allocatables>
    </employeeAllocation>
    <employeeAllocation>
        <allocatables
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns3:Duty">
            <startTime>2020-11-03T21:00:00.000</startTime>
            <endTime>2020-11-04T06:45:00.000</endTime>
            <shortName>TPL1030</shortName>
            <rosterAbbreviation>DLT</rosterAbbreviation>
        </allocatables>
    </employeeAllocation>
</ns3:EmployeeAllocationResponse>

这是“employeeAllocation”类

public class EmployeeAllocation
{
    [XmlElement("employee")]
    public Employee Employee { get; set; }

    [XmlElement("allocatables")]
    public List<Alloctable> Alloctables { get; set; }
}

这是“可分配”类

[XmlType(Namespace = "http://employeeallocation.intf.mb.ivu.de/", TypeName = "Duty")]
public class Alloctable
{
    [XmlElement("startTime", Namespace = "")]
    public string StartTime { get; set; }
}

我的问题是我不知道如何将一种新的“alloctables”类型添加到我的 Alloctables 列表中。现在它可以处理 type="Duty" 但在尝试反序列化其他类型时崩溃了。

标签: c#xmlserialization

解决方案


我通过序列化一些测试数据并将其与您输入的 xml 数据进行比较来使其工作。请参阅下面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        const string FILENAME1 = @"c:\temp\test1.xml";
        static void Main(string[] args)
        {
            string xml = File.ReadAllText(FILENAME);
            StringReader sReader = new StringReader(xml);
            XmlReader xReader = XmlReader.Create(sReader);
            XmlSerializer serializer = new XmlSerializer(typeof(EmployeeAllocationResponse));

            EmployeeAllocationResponse r = new EmployeeAllocationResponse()
            {
                Allocatables = new List<Allocatables>() {
                    new Duty(),
                    new Absence()
                }
            };
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            XmlWriter writer = XmlWriter.Create(FILENAME1, settings);
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("ns2", "http://employeeallocation.intf.mb.ivu.de/fault");
            ns.Add("ns3", "http://employeeallocation.intf.mb.ivu.de/");
            ns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            serializer.Serialize(writer, r, ns);

            EmployeeAllocationResponse response = (EmployeeAllocationResponse)serializer.Deserialize(xReader);

        }
    }
    [XmlRoot(ElementName = "EmployeeAllocationResponse", Namespace = "http://employeeallocation.intf.mb.ivu.de/")]
    public class EmployeeAllocationResponse
    {
        [XmlArray(ElementName = "employeeAllocation", Namespace = "")]
        [XmlArrayItem(ElementName = "allocatables", Namespace = "")]
        public List<Allocatables> Allocatables { get; set; } 
    }
    [XmlRoot(ElementName = "allocatables", Namespace = "http://employeeallocation.intf.mb.ivu.de/")]
    [XmlInclude(typeof(Duty)), XmlInclude(typeof(Absence))]
    public class Allocatables
    {
        [XmlElement(ElementName = "startTime", Namespace = "")]
        public DateTime startTime { get; set; }
        [XmlElement(ElementName = "endTime", Namespace = "")]
        public DateTime endTime { get; set; }
    }
    [XmlRoot(ElementName = "Duty", Namespace = "http://employeeallocation.intf.mb.ivu.de/")]
    public class Duty : Allocatables
    {
        [XmlElement(ElementName = "shortName", Namespace = "")]
        public string shortName { get; set; }
        [XmlElement(ElementName = "rosterAbbreviation", Namespace = "")]
        public string rosterAbbreviation { get; set; }
    }
    [XmlRoot(ElementName = "Absence", Namespace = "http://employeeallocation.intf.mb.ivu.de/")]
    public class Absence : Allocatables
    {
        [XmlElement(ElementName = "typeAbbreviation", Namespace = "")]
        public string typeAbbreviation { get; set; }
        [XmlElement(ElementName = "typeLongname", Namespace = "")]
        public string typeLongname { get; set; }
        [XmlElement(ElementName = "type", Namespace = "")]
        public string type { get; set; }
    }
}

推荐阅读