Linq to XML 元素内的元素

Linq to XML Element inside Element

我写了一个方法来读取 XML 并将信息写入对象。 XML 包含带有信息的元素,但一些信息是封装的,我不知道如何从中获取信息。 XML 包含大约 200 个 "results".

XML结构

 <result id="xxxxx">
      <name>Name</name>
      <age>25</age>
      <info>
           <x>Some text</x>
           <y>More Text</y>
      </info>
 </result>

代码

XDocument rootDocument = XDocument.Load(file);
var xy = from r in rootDocument.Descendants("result")
        select new
        {
            Name = r.Element("name")
            Age = r.Element("age"),
            x = r.Element("info").Element("x"),
            y = r.Element("info").Element("y"),
        };

foreach (var r in xy)
{
    Object o = new Object()
    {
        Name = r.Name,
        Age = r.Age,
        x = r.x,
        y = r.y
    };
}

错误 对象引用未设置为对象的实例。

错误发生在行

  x = r.Element("info")...

和下一个。

您可以执行以下操作:

var query = from r in rootDocument.Descendants("result")
            select new
            {
                Name = (string)r.Element("name"),
                Age = (int?)r.Element("age"),
                x = (string)r.Elements("info").Elements("x").SingleOrDefault(),
                y = (string)r.Elements("info").Elements("x").SingleOrDefault(),
            };
var resultList = query.ToList();

备注:

  • 一旦您选择了具有原始值的 XElement,您可以将元素转换为 c# 原始值,例如 stringint? 通过使用一个XElementexplicit casting operators,像这样:

    Name = (string)r.Element("name")
    Age = (int?)r.Element("age")
    
  • 您看到 对象引用未设置到对象的实例 异常这一事实表明元素意外丢失。如果 <result> 元素之一缺少 <info> 子元素,则很容易发生这种情况。表达式

    r.Elements("info").Elements("x")
    

    returns 所有 个名为 <x> 的子元素的 <info> 个子元素。然后 SingleOrDefault() returns 该序列的唯一元素,如果序列为空,则为默认值。这可以防止缺少 <info> 的情况。

  • 同样,如果缺少 <age> 元素,尝试将其转换为 int 将引发空引用异常,因为 int 是值类型。强制转换为 int? 而不是 returns null 而不是抛出异常。

  • 最终 ToList() 计算查询并 returns 列表中的结果。

示例 fiddle.