使用LINQ反序列化XML时所有字段返回null问题求解
问题原因及解决步骤
首先明确核心问题出在XML结构和读取逻辑不匹配,以及代码存在编写错误,具体解决方式如下:
1. 核心问题:XML层级结构错误
你当前的XML所有站点属性、行李房属性都直接挂在根节点<RailwayStations>下,<RailwayStation />是完全没有子元素的空节点,所以你从<RailwayStation>节点下查询子元素自然全部返回null。
更合理的XML结构应该把每个站点的属性、对应行李房节点都包在<RailwayStation>内部,层级更清晰也符合通用序列化规范,修正后的XML示例:
<?xml version="1.0" encoding="utf-8"?> <RailwayStations> <RailwayStation> <RailwayStationName>Verdansk</RailwayStationName> <RailwayStationCountOfWays>10</RailwayStationCountOfWays> <RailwayStationCountOfLuggageRooms>3</RailwayStationCountOfLuggageRooms> <LuggageRooms> <LuggageRoom> <RailwayStationLuggageRoomHeight>10</RailwayStationLuggageRoomHeight> <RailwayStationLuggageRoomWidth>20</RailwayStationLuggageRoomWidth> <RailwayStationLuggageRoomDepth>30</RailwayStationLuggageRoomDepth> </LuggageRoom> <LuggageRoom> <RailwayStationLuggageRoomHeight>11</RailwayStationLuggageRoomHeight> <RailwayStationLuggageRoomWidth>21</RailwayStationLuggageRoomWidth> <RailwayStationLuggageRoomDepth>31</RailwayStationLuggageRoomDepth> </LuggageRoom> <LuggageRoom> <RailwayStationLuggageRoomHeight>12</RailwayStationLuggageRoomHeight> <RailwayStationLuggageRoomWidth>22</RailwayStationLuggageRoomWidth> <RailwayStationLuggageRoomDepth>32</RailwayStationLuggageRoomDepth> </LuggageRoom> </LuggageRooms> </RailwayStation> </RailwayStations>
2. 原有代码的额外错误
你的代码还存在两处明显编写问题:
- 读取行李房时仍然从根节点查询
<RailwayStation>节点,本身该节点为空,自然读不到值 - 赋值行李房宽度、深度时,错误地都取了
RailwayStationLuggageRoomHeight的值
3. 修正后的读取代码(适配上述修正后的XML结构)
var xDoc = XDocument.Load(fileName); var obj = from stationElem in xDoc.Root?.Elements("RailwayStation") select new RailwayStation() { RailwayStationName = stationElem.Element("RailwayStationName")?.Value, RailwayStationCountOfWays = Convert.ToInt32(stationElem.Element("RailwayStationCountOfWays")?.Value ?? "0"), RailwayStationCountOfLuggageRooms = Convert.ToInt32(stationElem.Element("RailwayStationCountOfLuggageRooms")?.Value ?? "0"), LuggageRooms = (from roomElem in stationElem.Element("LuggageRooms")?.Elements("LuggageRoom") select new LuggageRoom() { _luggageRoomHeight = Convert.ToInt32(roomElem.Element("RailwayStationLuggageRoomHeight")?.Value ?? "0"), _luggageRoomWidth = Convert.ToInt32(roomElem.Element("RailwayStationLuggageRoomWidth")?.Value ?? "0"), _luggageRoomDepth = Convert.ToInt32(roomElem.Element("RailwayStationLuggageRoomDepth")?.Value ?? "0"), }).ToList() }; return obj;
4. 若你坚持不修改原有XML结构,可使用以下适配代码
如果不方便调整XML生成逻辑,也可以直接适配你当前的扁平XML结构:
var xDoc = XDocument.Load(fileName); var root = xDoc.Root; // 直接从根节点读取站点基础属性 var station = new RailwayStation() { RailwayStationName = root.Element("RailwayStationName")?.Value, RailwayStationCountOfWays = Convert.ToInt32(root.Element("RailwayStationCountOfWays")?.Value ?? "0"), RailwayStationCountOfLuggageRooms = Convert.ToInt32(root.Element("RailwayStationCountOfLuggageRooms")?.Value ?? "0"), LuggageRooms = new List<LuggageRoom>() }; // 按顺序匹配行李房的长宽高参数 var heights = root.Elements("RailwayStationLuggageRoomHeight").Select(e => e.Value).ToList(); var widths = root.Elements("RailwayStationLuggageRoomWidth").Select(e => e.Value).ToList(); var depths = root.Elements("RailwayStationLuggageRoomDepth").Select(e => e.Value).ToList(); for (int i = 0; i < heights.Count; i++) { station.LuggageRooms.Add(new LuggageRoom() { _luggageRoomHeight = Convert.ToInt32(heights[i]), _luggageRoomWidth = Convert.ToInt32(widths[i]), _luggageRoomDepth = Convert.ToInt32(depths[i]), }); } return new List<RailwayStation> { station };
内容的提问来源于stack exchange,提问作者LNxD
相关产品推荐
相关产品推荐

