我写了一个方法来读取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")...
以及下一个。
答案 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(例如string
或int?
) }} 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。