我有一个这样的对象:
public class ClientCredentials
{
public string UserName { get; set; }
public string Password { get; set; }
public string Rights { get; set; }
}
和xml看起来像这样:
<?xml version="1.0" encoding="utf-8" ?>
<users>
<user>
<username>playerone</username>
<password>654321</password>
<rights>true</rights>
</user>
<user>
<username>amoreroma</username>
<password>123456789</password>
<rights>false</rights>
</user>
</users>
我只想在LINQ 之后生成一个 ClientCredentials 对象列表到给定的XML
我试过这样:
XDocument document = XDocument.Load(@"path\to\file\file.xml");
var query = document.Descendants("users").Select(s => new ClientCredentials
{
UserName = s.Element("username").Value,
Password = s.Element("password").Value,
Rights = s.Element("rights").Value
}).ToList();
但我收到错误引用没有设置为对象的实例。
答案 0 :(得分:3)
您需要Descendants("user")
而不是Descendants("users")
。您的username
,password
和rights
元素是user
元素的子元素。不是Users
元素。这就是你得到NullReferenceException.
的原因你也可以使用显式强制转换来避免NullReferenceException
。如果找不到任何元素,你的代码仍然会抛出异常,因为你是直接访问Value
属性。
var query = document.Descendants("user").Select(s => new ClientCredentials
{
UserName = (string)s.Element("username"),
Password = (string)s.Element("password"),
Rights = (string)s.Element("rights")
}).ToList();
答案 1 :(得分:0)
这是使用查询语法表示的LINQ查询。而不是使用Descendants()
方法,查询通过Root.Elements("user")
包含了感兴趣元素的直接路径:
var query =
from el in document.Root.Elements("user")
select new ClientCredentials
{
UserName = (string)el.Element("username"),
Password = (string)el.Element("password"),
Rights = (string)el.Element("rights")
};
为了演示此查询,我使用您提供的示例XML数据创建了一个程序。此外,您询问缺少的元素是否会生成异常。正如@ Selman22指出的那样,您可以通过删除.Value
属性并使用{{1}来避免缺少元素的异常} 投。这样做会导致为缺少的元素返回空字符串。为了表明这一点,我添加了第三个(string)
元素并省略了它的<user>
子元素。
请参阅下面的示范程序格式化输出,然后是程序本身。
演示程序输出
<rights>
演示计划
请注意,我在查询表达式的末尾删除了UserName:[playerone]
Password:[654321]
Rights:[true]
--
UserName:[amoreroma]
Password:[123456789]
Rights:[false]
--
UserName:[norights]
Password:[20140215]
Rights:[]
--
,因为这里不需要它。 (这意味着ToList()
只是query
。)
IEnumerable