c# - 在 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" 但在尝试反序列化其他类型时崩溃了。
解决方案
我通过序列化一些测试数据并将其与您输入的 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; }
}
}
推荐阅读
- javascript - 无法将服务器上的 JSON 文件提取到 Javascript 数组中
- sprite-kit - SKEmitterNode 在用作另一个参考节点中的参考节点时不起作用
- math - 给定位移和离散时间的恒定减速度的最大可停止速度
- python - python double for 在列表理解中
- graph - 原始图的拓扑排序是否与转置图的 dfs 相同
- go - Beego:模块的路由问题
- swift - 快速处理零
- javascript - 你能在javascript中引用一个解构函数参数吗?
- ruby-on-rails - 使用 ActiveRecord 查询记录列表,其中每个项目的外键都存在于哈希中
- azure - 如何“私下”从 Web App 连接到另一个区域的 SQL 数据库?