gpt4 book ai didi

c# - 从平面 XML 反序列化的嵌套类

转载 作者:数据小太阳 更新时间:2023-10-29 02:26:08 25 4
gpt4 key购买 nike

如果我有一个看起来像这样的 xml 文件

<Foo>
<Name>Some Data</Name>
<Bar_Data>Other Data</Bar_Data>
<Bar_MoreData>More Data</Bar_MoreData>
</Foo>

我想把它变成一个看起来像这样的 C# 类

public class Foo
{
public string Name {get; set; }
public Bar Bar { get; set; }
}

public class Bar
{
public string Data { get; set; }
public string MoreData { get; set; }
}

是否有任何方法可以仅通过简单的数据注释( XmlRootXmlElement 等)来实现这一点,或者这是我实现 IXmlSerializable 的唯一选择? ?

编辑:请注意,我只需要反序列化数据。我从第 3 方来源获取 XML,我不需要序列化 ​​Foo返回到 XML(如果这样更容易)。

最佳答案

一种选择是使用 XmlAnyElementAttribute,如下所示:

public class Foo
{
public string Name { get; set; }
public Bar Bar { get; set; }

[XmlAnyElementAttribute]
public XmlElement[] BarElements
{
get { return null; }
set
{
Bar = new Bar();
var barType = Bar.GetType();
foreach (var prop in value)
barType.GetProperty(prop.Name.Substring(4)).SetValue(Bar, prop.InnerText);
}
}
}

public class Bar
{
public string Data { get; set; }
public string MoreData { get; set; }
}

当 XmlSerializer 无法识别某个元素时,它会将其添加到由 XmlAnyElementAttribute 标记的 XmlElement[] 类型的属性中。这是您可以处理 Bar 属性的地方。我在那里使用反射来展示这个想法。

另一种选择是反序列化两次并将 Bar 与 Foo 连接起来:

public class Foo
{
public string Name { get; set; }
public Bar Bar { get; set; }
}

[XmlRoot("Foo")]
public class Bar
{
[XmlElement("Bar_Data")]
public string Data { get; set; }
[XmlElement("Bar_MoreData")]
public string MoreData { get; set; }
}

var foo = (Foo) new XmlSerializer(typeof (Foo)).Deserialize(...);
var bar = (Bar) new XmlSerializer(typeof (Bar)).Deserialize(...);
foo.Bar = bar

另一个不影响被反序列化的类的选项:

public class Foo
{
public string Name { get; set; }
public Bar Bar { get; set; }
}

public class Bar
{
public string Data { get; set; }
public string MoreData { get; set; }
}

var fooSerializer = new XmlSerializer(typeof (Foo));
fooSerializer.UnknownElement += (sender, e) =>
{
var foo = (Foo) e.ObjectBeingDeserialized;
if(foo.Bar == null)
foo.Bar = new Bar();
var propName = e.Element.Name.Substring(4);
typeof(Bar).GetProperty(propName).SetValue(foo.Bar, e.Element.InnerText);
};

var fooInstance = fooSerializer.Deserialize(...);

如果双重反序列化或反射在性能方面存在问题,那么您可以创建一个代理代理类:

    [XmlRoot("Foo")]
public class FooSurrogate
{
public string Name { get; set; }
public string Bar_Data { get; set; }
public string Bar_MoreData { get; set; }

public Foo ToFoo()
{
return new Foo
{
Name = Name,
Bar = new Bar
{
Data = Bar_Data,
MoreData = Bar_MoreData
}
};
}
}

var seializer = new XmlSerializer(typeof (FooSurrogate));
var foo = ((FooSurrogate) seializer.Deserialize(...)).ToFoo();

关于c# - 从平面 XML 反序列化的嵌套类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31885232/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com