Linq元素内的XML元素

问题描述:

我写了一个读取XML并将信息写入对象的方法。 XML包含了包含这些信息的元素,但是其中一些信息被封装,我无法弄清楚如何从中获取信息。 XML包含大约200个“结果”。Linq元素内的XML元素

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

和下面的一个。

+0

您是否有错误或警告?我没有看到问题(除了'Object o = new Object();')这一行的错误语法外)。 –

+0

是的,它被编辑。我不知道为什么。我会再次添加它。 – Thomas

+0

是否有任何XML节点,其中'info'没有'x'和'y'值? –

你可以做到以下几点:

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,您可以将元素转换为AC#基本如stringint?使用XElementexplicit casting operators之一,如下所示:

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

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

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

  • 同样,如果<age>元素丢失,试图将其转换为int会抛出空引用异常,因为int是值类型。代替投掷异常,而不是抛出int?而是返回null。

  • 最后的ToList()评估查询并返回列表中的结果。

样品fiddle

+0

完美解释和抽样。谢谢! – Thomas