c# - XmlSerializer 在定义为 XmlElement 的自闭标记后将 null 设置为属性

标签 c# xml serialization xmlserializer

想象一下具有如下所示的 XML 结构:

[XmlRoot("Foo")]
public class Foo
{
    [XmlElement("Bar")]
    public Bar Bar { get; set; }
    [XmlElement("SuperImportant")]
    public SuperImportant SuperImportant { get; set; }
}

[XmlRoot("Bar")]
public class Bar
{
    [XmlElement("Baz")]
    public XmlElement Baz { get; set; }
}

[XmlRoot("SuperImportant")]
public class SuperImportant
{
    [XmlElement("MegaImportant")]
    public string MegaImportant { get; set; }
}

出于某种原因,Baz 定义为 XmlElement

现在检查这段代码:

var template = @"
<Foo>
  <Bar>
    {0}
  </Bar>
  <SuperImportant>
    <MegaImportant>42</MegaImportant>
  </SuperImportant>
</Foo>";

var selfClosed = new StringReader(String.Format(template, "<Baz/>"));    

var openClosePair = new StringReader(String.Format(template, "<Baz></Baz>"));

XmlSerializer xmlSerializer = new XmlSerializer(typeof(Foo));

var o1 = (Foo)xmlSerializer.Deserialize(selfClosed);
Console.WriteLine(o1.SuperImportant == null); // True, it's not there

var o2 = (Foo)xmlSerializer.Deserialize(openClosePair);
Console.WriteLine(o2.SuperImportant == null); // False, it's there

如您所见,如果在类定义中定义为 XmlElement 的某些标记似乎是自关闭的,则其父标记之后的元素为 null。如何配置 XmlSerializer 将自闭标签视为开闭对? SuperImportant 在这两种情况下都应该被反序列化,但前者不是,这是错误的。

最佳答案

您应该标记属性 Baz[XmlAnyElement("Baz")]像这样:

[XmlRoot("Bar")]
public class Bar
{
    [XmlAnyElement("Baz")]
    public XmlElement Baz { get; set; }
}

docs 中所述, 这个属性

Specifies that the member (a field that returns an array of XmlElement or XmlNode objects) contains objects that represent any XML element that has no corresponding member in the object being serialized or deserialized.
...
You can also apply the XmlAnyElementAttribute to a field that returns a single XmlElement object. If you do so, you must use the properties and methods of the XmlElement class to recursively iterate through the unknown elements.

应用属性后,Baz属性将正确捕获 <Baz/><Baz></Baz>元素而不干扰后续节点的反序列化。 [XmlElement("Baz")] 看起来确实很奇怪导致您看到的不一致,但由于 [XmlAnyElement("Baz")]旨在处理这种情况,应该改用它。

示例工作 .Net fiddle here .

关于c# - XmlSerializer 在定义为 XmlElement 的自闭标记后将 null 设置为属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50756656/

相关文章:

html - XPath 选择两个标题之间的所有元素?

c# - 更改 Crystal Report 的 XML 数据源

c++ - Boost::Serialization Mpi 发送用户定义类型的数组

serialization - 带有混淆的 Proto-buf 序列化

c# - XML 序列化 - .NET 4.0 中的不同结果

c# - 如何在 Mac 上从命令行编译 Mono 项目

c# - 如何用更丰富的类型覆盖接口(interface)方法中定义的参数?

c# - xsd2code - 反序列化 xml 文件时出现问题

c# - 是否可以读取.exe文件?

c# - 从 .NET 操作 Hyper-V