Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何基于子对象c的属性值反序列化XML对象?_C#_Xml - Fatal编程技术网

C# 如何基于子对象c的属性值反序列化XML对象?

C# 如何基于子对象c的属性值反序列化XML对象?,c#,xml,C#,Xml,如何基于子对象的属性值反序列化XML对象 例如,我得到了这个 <List> <Person> <M id= Name v="Chris"> <M id= Year v="12"> <M id= Haircolor v="blond"> <M id= HairLength v="10"> </Person > <Person> <M id= Na

如何基于子对象的属性值反序列化XML对象

例如,我得到了这个

<List>
  <Person>
    <M id= Name v="Chris">
    <M id= Year v="12">
    <M id= Haircolor v="blond">
    <M id= HairLength v="10">
  </Person >
  <Person>
    <M id= Name v="Sara">
    <M id= Year v="9">
    <M id= Haircolor v="Brown">
    <M id= HairLength v="20">
  </Person >
  <Person>
    <M id= Name v="Noelle">
    <M id= Year v="20">
    <M id= Haircolor v="Gray">
    <M id= HairLength v="30">
  </Person >      <Person>
</List>
我希望Id为name的M元素对应于类中的name,并且M元素中的Id year对应于year等等

我怎样才能做到这一点

给定加载了XML的XmlDocument,这将使用XPath查询来解析文件:

IEnumerable<Person> ReadPeople(XmlDocument document)
{
    var result = new List<Person>();
    var root = document.DocumentElement;
    var personNodes = root.SelectNodes("Person");
    foreach (XmlElement personNode in personNodes)
    {
        var person = new Person
        {
            Name = personNode.SelectSingleNode("M[@id='Name']")?.Attributes["v"]?.Value,
            Haircolor = personNode.SelectSingleNode("M[@id='Haircolor']")?.Attributes["v"]?.Value,
            HairLength = personNode.SelectSingleNode("M[@id='HairLength']")?.Attributes["v"]?.Value,
            Year = personNode.SelectSingleNode("M[@id='Year']")?.Attributes["v"]?.Value
        };

        result.Add(person);
    }
    return result;
}
它做了以下工作:

选择根元素中的所有Person节点 对于每个Person节点,选择具有每个预期id属性的M元素,并将v属性的值指定给Person对象的相应属性。 为了进行测试,我必须清理XML的某些方面,因此我正在加载的文档如下所示:

public class Person 
{    
  public string Name {get; set;}
  public string Year {get; set;}      
  public string Haircolor {get; set;}      
  public string HairLength {get; set;}
}
<?xml version="1.0" encoding="utf-8" ?>
<List>
  <Person>
    <M id= "Name" v="Chris"/>
    <M id= "Year" v="12"/>
    <M id= "Haircolor" v="blond"/>
    <M id= "HairLength" v="10"/>
  </Person >
  <Person>
    <M id= "Name" v="Sara"/>
    <M id= "Year" v="9"/>
    <M id= "Haircolor" v="Brown"/>
    <!--<M id= "HairLength" v="20"/>-->
  </Person >

</List>
原始的格式不正确-缺少结束标记和属性值周围的引号

这包括删除一个元素以确保正确处理空值

或者,如果您喜欢重复性稍低的内容,可以使用本地函数检索给定id并使用LINQ查询

IEnumerable<Person> ReadPeople(XmlDocument document)
{
    string GetAttribute(XmlElement personNode, string id) =>
        personNode.SelectSingleNode($"M[@id='{id}']")?.Attributes["v"]?.Value;

    return document.DocumentElement.SelectNodes("Person").Cast<XmlElement>()
        .Select(node =>
            new Person
            {
                Name = GetAttribute(node, "Name"),
                Haircolor = GetAttribute(node, "Haircolor"),
                HairLength = GetAttribute(node, "HairLength"),
                Year = GetAttribute(node, "Year")
            });
}

您能够反序列化XML吗?如果你是,那就是战斗的大部分。不要试图将它直接反序列化到Person类中。相反,将其反序列化为任何内容,然后将其映射到所需的最终类。换句话说,将你不想要的奇怪的反序列化类转换成你想要的更好的类。我很好地反序列化了它,但我的问题是,例如,因为我使用了order值,每当Name元素没有值时,year值就会自动落入Name属性中。。。
IEnumerable<Person> ReadPeople(XmlDocument document)
{
    string GetAttribute(XmlElement personNode, string id) =>
        personNode.SelectSingleNode($"M[@id='{id}']")?.Attributes["v"]?.Value;

    return document.DocumentElement.SelectNodes("Person").Cast<XmlElement>()
        .Select(node =>
            new Person
            {
                Name = GetAttribute(node, "Name"),
                Haircolor = GetAttribute(node, "Haircolor"),
                HairLength = GetAttribute(node, "HairLength"),
                Year = GetAttribute(node, "Year")
            });
}