简体   繁体   English

通过 LINQ 从 XML 反序列化

[英]DeSerialize From XML By LINQ

So, I have XML file:所以,我有 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>

And, I want to read from it.而且,我想从中阅读。 My code below returns null to all fields我下面的代码向所有字段返回 null

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;

Any suggestions?有什么建议? About XML File - it created by self-made method, where I add XElements to XDocument and save it.关于 XML 文件 - 它由自制方法创建,我将XElements添加到XDocument并保存它。

Based on the expectation in your code, it looks like your XML is not well-formed, this is what your code is expecting:根据您的代码中的期望,您的 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>

Notice now that RailwayStations (plural) now has multiple child elements called RailwayStation .现在请注意, RailwayStations (复数)现在有多个名为RailwayStation子元素。 The same then goes for the Luggage rooms, the code is actually making the wrong assumption for these anyway, but the data should be structured so that each luggage room is contained within an outer element, in this example I called it LuggageRooms行李间也是如此,无论如何,代码实际上对这些假设做了错误的假设,但数据的结构应该使每个行李间都包含在一个外部元素中,在这个例子中我称之为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;

It looks like you have an XY problem here, if you are constructing the XML as well, please check the logic in there to make sure that it makes sense.看起来你在这里有一个XY 问题,如果你也在构建 XML,请检查那里的逻辑以确保它有意义。

If you are constructing this XML, then consider a schema with simpler named elements:如果您正在构建此 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>

Then your code could be something like this:那么你的代码可能是这样的:

 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;

I realize this is a significant structure change, but it will simplify all future processing and reduce the bytes going across the wire.我意识到这是一个重大的结构变化,但它将简化所有未来的处理并减少通过线路的字节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM