XmlDeserialize基于属性值的条件反序列化

时间:2012-05-04 20:42:09

标签: c# xml xml-serialization

我正在尝试反序列化以下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);

当我运行此操作时,我收到带有消息

的InvalidOperationException
  

反映“测试”类型的错误。

如果我注释掉Description属性,它就可以了。我可以获取属性值或文本,但我不能得到XmlText,元素是字符串,“name”属性具有特定值。

如果不使用LINQ,这是否可行?

3 个答案:

答案 0 :(得分:1)

根据我的评论:

  

如果不改变某些东西,肯定无法做到。你是   告诉.NET,当它是一个属性时,Description是一个元素   'string'元素。使用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"] };

答案 1 :(得分:0)

原因是您没有按预期使用XmlElement,元素名称“string”必须是该类唯一的。不考虑“名称”属性。

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

答案 2 :(得分:0)

为此您需要:

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;}
}

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