Xml基于属性值反序列化条件反序列化

本文关键字:反序列化 属性 条件 于属性 Xml | 更新日期: 2023-09-27 18:33:09

我正在尝试反序列化以下XML:

<Test><string name="Name">Test name</string><string name="Description">Some fake description.</string></Test>

进入以下类。

[XmlRoot("Test")]
public class Test
{
 [XmlElement("string")]
 public string Name;
 [XmlElement("string")]
 public string Description;
}

使用我正在做的代码。

var xml = @"<Test><string name=""Name"">Test name</string><string name=""Description"">Some fake description.</string></Test>";
XmlReader reader = new XmlTextReader(new StringReader(xml));
XmlSerializer serializer = new XmlSerializer(typeof(Test));
serializer.Deserialize(reader);

当我运行它时,我收到一个带有消息的无效操作异常

出现反映类型"测试"的错误。

如果我注释掉"描述"属性,它可以工作。我可以获取属性值或文本,但我不能只获取带有元素字符串且"name"属性具有特定值的 XmlText。

这甚至可以在不使用 LINQ 的情况下实现吗?

Xml基于属性值反序列化条件反序列化

根据我的评论:

当然,如果不改变一些东西就无法做到这一点。你是 告诉 .NET 说明是一个元素,当它是 "字符串"元素。使用 LINQ

下面是 LINQ 的一个示例,将 XML 与类进行扩展和解耦非常简单(这通常是一件好事!

var xml = @"<Test><string name=""Name"">Test name</string><string name=""Description"">Some fake description.</string></Test>";
var xdoc = XDocument.Parse(xml);
var output = from test in xdoc.Elements("Test")
             let strings = test.Elements("string").ToDictionary(e => e.Attribute("name").Value, e => e.Value)
             select new Test () { Name = strings["Name"],
                                  Description = strings["Description"] };

原因是您没有按预期使用 XmlElement,元素名称"字符串"必须是类的唯一。不考虑"名称"属性。

因此,总而言之,不可能自动反序列化该 xml 文档,您需要自己实现反序列化方法。

为此,

您需要:

public class Foo {
    [XmlAttribute("name")]
    public string Name {get;set;}
    [XmlText]
    public string Value {get;set;}
}

然后,在父类型中:

[XmlRoot("Test")]
public class Test
{
    [XmlElement("string")]
    public List<Foo> Items {get;set;}
}

这是处理该形状 XML 的唯一方法,除非您使用IXmlSerializable(非常困难)。