C# 反序列化 XML 文件到列表

标签 c# xml deserialization

我想将 XML 反序列化为对象列表。

这是我的顶级 C# 类:

[XmlRoot("Events")]
[XmlType("Events")]
[Serializable]
public class WinEventLogList
{

    public WinEventLogList() { Items = new List<WinEventLog>(); }

    [XmlElement("Event")]
    public List<WinEventLog> Items { get; set; }

}

[XmlRoot("Event")]
[XmlType("Event")]
[Serializable]
public class WinEventLog
{

    [XmlElement("System")]
    [JsonPropertyName("system")]
    public EventSystem System { get; set; } = new EventSystem();

    [XmlElement("EventData")]
    [JsonPropertyName("eventData")]
    public EventData EventData { get; set; } = new EventData();

}

这是我需要反序列化的示例 XML:

<?xml version="1.0" encoding="utf-8"?>
<Events>
  <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
    <System>Omitted tags go in here</System>
    <EventData>Omitted tags go in here</EventData>
  </Event>
  <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
    <System>Omitted tags go in here</System>
    <EventData>Omitted tags go in here</Event>
  <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
    <System>Omitted tags go in here</System>
    <EventData>Omitted tags go in here</EventData>
  </Event>
  <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
    <System>Omitted tags go in here</System>
    <EventData>Omitted tags go in here</EventData>
  </Event>
  <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
    <System>Omitted tags go in here</System>
    <EventData>Omitted tags go in here</EventData>
  </Event>
</Events>

这是我尝试过的两种不同方法,均来自 this stackoverflow question .

首先,尝试使用包装类WinEventLogList

using var stream = File.OpenRead("path/to/my/xml/file.xml");
using var reader = new StreamReader(stream);
var serializer = new XmlSerializer(typeof(WinEventLogList));
var list = serializer.Value.Deserialize(reader) as WinEventLogList;
var winEventLogs = list.Items;

然后,尝试直接在序列化器中使用普通的List

using var stream = File.OpenRead("path/to/my/xml/file.xml");
using var reader = new StreamReader(stream);
var serializer = new XmlSerializer(
    typeof(List<WinEventLog>),  
    new XmlRootAttribute("Events"));
var winEventLogs = serializer.Value.Deserialize(reader) as List<WinEventLog>;

在这两种情况下,生成的 winEventLogs 变量都是空列表。 为什么会出现这种情况?如何纠正?

最佳答案

XML 中一个经常被忽视的组件是 namespaces 。它们实际上是[反]序列化过程中不可或缺的一部分。
您几乎已经完成了,只需在对象中指定 namespace 以匹配 XML。

这是一个工作片段:

void Main() {
  using var reader = new StringReader(xmlStr);
  var serializer = new XmlSerializer(typeof(WinEventLogList));
  var list = (WinEventLogList)serializer.Deserialize(reader)!;
  list.Dump();
}

[XmlRoot("Events")]
public class WinEventLogList {
  // Namespaces are extremely important!
  [XmlElement("Event", Namespace="http://schemas.microsoft.com/win/2004/08/events/event")]
  public List<WinEventLog> Items { get; set; } = new();
}

public class WinEventLog {
  [XmlElement] public int System { get; set; }
  [XmlElement] public int EventData { get; set; }
}

string xmlStr = """
<?xml version='1.0' encoding='utf-8'?>
<Events>
  <Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
    <System>1</System>  <EventData>2</EventData>
  </Event>
  <Event xmlns='http://schemas.microsoft.com/win/2004/08/events/event'>
    <System>3</System>  <EventData>4</EventData>
  </Event>
</Events>
""";

关于C# 反序列化 XML 文件到列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75153057/

相关文章:

java - Gson : deserialize time serialized by Jackson

c# - 优化Entity框架Query,避免延迟加载

c# - 模型上的 MVC 3.0 十进制数验证

c# - C# 中的抽象类继承与真实类继承

java - 我应该如何在Android问答游戏中创建question_bank?

java - Jaxb 编码 Point 变量

html - 从单行输出中删除 html/xml <tags> 的最简单方法

c# - 企业库 6 Microsoft.Practices.EnterpriseLibrary.Caching 丢失?

java - Serializable - writeObject()/ReadObject 和 Externalizable - Java 中的 readExternal()/writeExternal() 有什么区别?

java - 确定基于 XML 文件的类型以指定相应的处理程序