Linq到Element内的XML元素

时间:2017-10-06 06:15:31

标签: c# xml linq-to-xml

我写了一个方法来读取XML并将信息写入对象。 XML包含带有信息的元素,但是一些信息是封装的,我无法弄清楚如何从中获取信息。 XML包含大约200个"结果"。

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")...

以及下一个。

1 个答案:

答案 0 :(得分:3)

您可以执行以下操作:

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后,您可以使用{{1}中的一个将元素转换为ac#primitive(例如stringint?) }} explicit casting operators,就像这样:

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

    <info>

    返回名为r.Elements("info").Elements("x") 的子元素名为<x>所有子元素。然后SingleOrDefault()返回该序列的唯一元素,如果序列为空则返回默认值。这可以防止<info>丢失时的情况。

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

  • 最终ToList()评估查询并将结果返回到列表中。

示例fiddle