通过 LINQ 从 XML 反序列化

DeSerialize From XML By LINQ

所以,我有 XML 个文件:

<?xml version="1.0" encoding="utf-8"?>
<RailwayStations>
  <RailwayStation />
  <RailwayStationName>Verdansk</RailwayStationName>
  <RailwayStationCountOfWays>10</RailwayStationCountOfWays>
  <RailwayStationCountOfLuggageRooms>3</RailwayStationCountOfLuggageRooms>
  <RailwayStationLuggageRoomHeight>10</RailwayStationLuggageRoomHeight>
  <RailwayStationLuggageRoomWidth>20</RailwayStationLuggageRoomWidth>
  <RailwayStationLuggageRoomDepth>30</RailwayStationLuggageRoomDepth>
  <RailwayStationLuggageRoomHeight>11</RailwayStationLuggageRoomHeight>
  <RailwayStationLuggageRoomWidth>21</RailwayStationLuggageRoomWidth>
  <RailwayStationLuggageRoomDepth>31</RailwayStationLuggageRoomDepth>
  <RailwayStationLuggageRoomHeight>12</RailwayStationLuggageRoomHeight>
  <RailwayStationLuggageRoomWidth>22</RailwayStationLuggageRoomWidth>
  <RailwayStationLuggageRoomDepth>32</RailwayStationLuggageRoomDepth>
</RailwayStations>

而且,我想从中阅读。我下面的代码 returns 所有字段都为空

var xDoc = XDocument.Load(fileName);

            var obj = from xElement in xDoc.Element("RailwayStations")?.Elements("RailwayStation")
                select new RailwayStation()
                {
                    RailwayStationName = xElement.Element("RailwayStationName")?.Value,
                    RailwayStationCountOfWays = Convert.ToInt32(xElement.Element("RailwayStationCountOfWays")?.Value),
                    RailwayStationCountOfLuggageRooms =
                        Convert.ToInt32(xElement.Element("RailwayStationCountOfLuggageRooms")?.Value),
                    
                    LuggageRooms = (from element in xDoc.Element("RailwayStations")?.Elements("RailwayStation")
                        select new LuggageRoom()
                        {
                            _luggageRoomHeight = Convert.ToInt32(element.Element("RailwayStationLuggageRoomHeight")?.Value),
                            _luggageRoomWidth = Convert.ToInt32(element.Element("RailwayStationLuggageRoomHeight")?.Value),
                            _luggageRoomDepth = Convert.ToInt32(element.Element("RailwayStationLuggageRoomHeight")?.Value),
                        }).ToList()
                };
            return obj;

有什么建议吗?关于 XML 文件 - 它是通过自制方法创建的,其中我将 XElements 添加到 XDocument 并保存它。

根据您的代码预期,您的 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>
  <RailwayStation>
    <RailwayStationName>Number 2</RailwayStationName>
    <RailwayStationCountOfWays>8</RailwayStationCountOfWays>
    <RailwayStationCountOfLuggageRooms>1</RailwayStationCountOfLuggageRooms>
    <LuggageRooms>
      <LuggageRoom>
        <RailwayStationLuggageRoomHeight>12</RailwayStationLuggageRoomHeight>
        <RailwayStationLuggageRoomWidth>22</RailwayStationLuggageRoomWidth>
        <RailwayStationLuggageRoomDepth>32</RailwayStationLuggageRoomDepth>          
      </LuggageRoom>
    </LuggageRooms>
  </RailwayStation>
</RailwayStations>

现在请注意 RailwayStations(复数)现在有多个名为 RailwayStation 的子元素。行李房也是如此,代码实际上对这些做出了错误的假设,但数据的结构应该使每个行李房都包含在一个外部元素中,在这个例子中我称之为 LuggageRooms

var xDoc = XDocument.Load(fileName);
var obj = from xElement in xDoc.Element("RailwayStations")?.Elements("RailwayStation")
          select new RailwayStation()
          {
              RailwayStationName = xElement.Element("RailwayStationName")?.Value,
              RailwayStationCountOfWays = Convert.ToInt32(xElement.Element("RailwayStationCountOfWays")?.Value),
              RailwayStationCountOfLuggageRooms =
                Convert.ToInt32(xElement.Element("RailwayStationCountOfLuggageRooms")?.Value),
            
              LuggageRooms = (from element in xElement.Elements("LuggageRooms")
                select new LuggageRoom()
                {
                    _luggageRoomHeight = Convert.ToInt32(element.Element("RailwayStationLuggageRoomHeight")?.Value),
                    _luggageRoomWidth = Convert.ToInt32(element.Element("RailwayStationLuggageRoomWidth")?.Value),
                    _luggageRoomDepth = Convert.ToInt32(element.Element("RailwayStationLuggageRoomDepth")?.Value),
                }).ToList()
          };
return obj;

看起来你在这里有一个XY problem,如果你也在构建XML,请检查那里的逻辑以确保它是有意义的。

如果您要构建此 XML,则考虑具有更简单命名元素的模式:

 <RailwayStation>
   <Name>Number 2</Name>
   <CountOfWays>8</CountOfWays>
   <CountOfLuggageRooms>1</CountOfLuggageRooms>
   <LuggageRooms>
     <LuggageRoom>
       <Height>12</Height>
       <Width>22</Width>
       <Depth>32</Depth>          
     </LuggageRoom>
   </LuggageRooms>
 </RailwayStation>

那么你的代码可能是这样的:

 var xDoc = XDocument.Load(fileName);
 var obj = from xElement in xDoc.Element("RailwayStations")?.Elements("RailwayStation")
           select new RailwayStation()
           {
               Name = xElement.Element("Name")?.Value,
               CountOfWays = Convert.ToInt32(xElement.Element("CountOfWays")?.Value),
               CountOfLuggageRooms = Convert.ToInt32(xElement.Element("CountOfLuggageRooms")?.Value),
             
               LuggageRooms = (from element in xElement.Elements("LuggageRooms")
                 select new LuggageRoom()
                 {
                     Height = Convert.ToInt32(element.Element("Height")?.Value),
                     Width = Convert.ToInt32(element.Element("Width")?.Value),
                     Depth = Convert.ToInt32(element.Element("Depth")?.Value),
                 }).ToList()
           };
 return obj;

我意识到这是一个重大的结构变化,但它将简化所有未来的处理并减少传输的字节数。