C# XML反序列化问题:如何正确反序列化含嵌套类、属性与列表的XML并解决Match列表为空的问题
解决XML反序列化时Match列表为空的问题
我帮你梳理下代码里的问题,一步步修改就能实现正确反序列化了:
核心问题分析
你的代码主要存在三个关键问题:
- XML节点大小写不匹配:XML是大小写敏感的,你类里的属性标记用了小写(比如
matchinfo),但原XML里是大写开头的节点(比如<MatchInfo>),导致无法匹配。 - 列表属性的标记错误:
BetradarLiveOdds里的Matchs属性用了[XmlArrayItem("match")],但原XML中<BetradarLiveOdds>直接包含<Match>节点,没有外层的数组容器(比如<Matchs>),这个标记不适用。 - Translation属性定义错误:原XML中每个
<Match>下只有一个<Translation>节点,你却定义成了List<Translation>,导致无法正确映射。
修改后的完整类定义
1. 根节点类 BetradarLiveOdds
[Serializable()] [XmlRoot("BetradarLiveOdds")] public class BetradarLiveOdds { [XmlAttribute("timestamp")] public long Timestamp { get; set; } [XmlAttribute("status")] public string Status { get; set; } // 直接匹配XML中的<Match>子节点,不需要外层数组容器 [XmlElement("Match")] public List<Match> Matchs { get; set; } }
2. Match类
[Serializable()] public class Match { [XmlAttribute("active")] public bool Active { get; set; } [XmlAttribute("booked")] public bool Booked { get; set; } [XmlAttribute("matchid")] public int MatchId { get; set; } [XmlAttribute("status")] public string Status { get; set; } // 修正大小写,和XML的<MatchInfo>完全匹配 [XmlElement("MatchInfo")] public MatchInfo MatchInfo { get; set; } // 原XML只有一个<Translation>节点,改为单个对象而非列表 [XmlElement("Translation")] public Translation Translation { get; set; } }
3. MatchInfo及基础子类
[Serializable()] public class MatchInfo { [XmlElement("DateOfMatch")] public long DateOfMatch { get; set; } [XmlElement("Sport")] public Sport Sport { get; set; } [XmlElement("Category")] public Category Category { get; set; } [XmlElement("Tournament")] public Tournament Tournament { get; set; } [XmlElement("HomeTeam")] public Team HomeTeam { get; set; } [XmlElement("AwayTeam")] public Team AwayTeam { get; set; } [XmlElement("TvChannels")] public string TvChannels { get; set; } } // 基础子类:Sport/Category/Tournament/Team结构相似 public class Sport { [XmlAttribute("id")] public int Id { get; set; } [XmlText] public string Name { get; set; } } public class Category { [XmlAttribute("id")] public int Id { get; set; } [XmlText] public string Name { get; set; } } public class Tournament { [XmlAttribute("id")] public long Id { get; set; } // 适配XML中较大的id值 [XmlText] public string Name { get; set; } } public class Team { [XmlAttribute("id")] public int Id { get; set; } [XmlText] public string Name { get; set; } }
4. Translation及多语言子类
[Serializable()] public class Translation { [XmlElement("Sport")] public TranslatedSport Sport { get; set; } [XmlElement("Category")] public TranslatedCategory Category { get; set; } [XmlElement("Tournament")] public TranslatedTournament Tournament { get; set; } [XmlElement("HomeTeam")] public TranslatedTeam HomeTeam { get; set; } [XmlElement("AwayTeam")] public TranslatedTeam AwayTeam { get; set; } } // 带多语言名称的子类 public class TranslatedSport { [XmlAttribute("id")] public int Id { get; set; } [XmlElement("Name")] public List<LocalizedName> Names { get; set; } } public class TranslatedCategory { [XmlAttribute("id")] public int Id { get; set; } [XmlElement("Name")] public List<LocalizedName> Names { get; set; } } public class TranslatedTournament { [XmlAttribute("id")] public long Id { get; set; } [XmlElement("Name")] public List<LocalizedName> Names { get; set; } } public class TranslatedTeam { [XmlAttribute("id")] public int Id { get; set; } [XmlElement("Name")] public List<LocalizedName> Names { get; set; } } // 多语言名称类 public class LocalizedName { [XmlAttribute("lang")] public string Language { get; set; } [XmlText] public string Value { get; set; } }
主程序代码优化(可选)
可以加上using语句自动释放文件流,同时添加异常处理:
static void Main(string[] args) { try { XmlSerializer serializer = new XmlSerializer(typeof(BetradarLiveOdds)); BetradarLiveOdds bet; using (FileStream fs = new FileStream("C:\\src\\bet2020\\RD_Live_Parsing\\meta\\hi.xml", FileMode.Open)) { bet = (BetradarLiveOdds)serializer.Deserialize(fs); } // 序列化到控制台验证结果 serializer.Serialize(Console.Out, bet); } catch (Exception ex) { Console.WriteLine($"反序列化出错:{ex.Message}"); } }
修改后运行代码,就能正确反序列化出包含Match数据的完整对象了。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

