如何在c#中的linq到xml之后生成对象数组[英] How to generate array of objects after LINQ to xml in C#

本文是小编为大家收集整理的关于如何在c#中的linq到xml之后生成对象数组的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我有这样的对象:

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>

我只想生成一个 clientcredentials的列表对象 linq 在给定的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();

但我得到错误参考未设置为对象的实例.

推荐答案

您需要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();

其他推荐答案

这是使用查询语法表示的LINQ查询.该查询不是使用Descendants()方法,而是通过Root.Elements("user") 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属性并使用(string) cast来避免缺失元素的异常.这样做将导致一个空字符串被返回到缺失的元素.为了显示这一点,我添加了第三个<user>元素,并省略了其<rights>子元素.

请参阅下文,以获取我的演示程序的格式输出,然后是该程序本身.

演示程序输出

UserName:[playerone]
Password:[654321]
Rights:[true]
--
UserName:[amoreroma]
Password:[123456789]
Rights:[false]
--
UserName:[norights]
Password:[20140215]
Rights:[]
--

演示程序

请注意,我在查询表达式末尾删除了ToList(),因为这里不需要. (这意味着query只是IEnumerable.)

using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

class ClientCredentialsDemo
{
    static public void Main(string[] args)
    {
        XDocument document = XDocument.Parse(GetXml());

        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")
                };

        foreach (var cc in query)
        {
            Console.WriteLine
                ("UserName:[{0}]\nPassword:[{1}]\nRights:[{2}]\n--",
                     cc.UserName,
                     cc.Password,
                     cc.Rights);
        }
    }

    static string GetXml()
    {
        return
            @"<?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>
                <user>
                    <username>norights</username>
                    <password>20140215</password>
                </user>
              </users>";
    }
}

public class ClientCredentials
{
    public string UserName { get; set; }
    public string Password { get; set; }
    public string Rights { get; set; }
}

本文地址:https://www.itbaoku.cn/post/1557115.html

问题描述

I have an object like this:

public class ClientCredentials
{
    public string UserName { get; set; }

    public string Password { get; set; }

    public string Rights { get; set; }
}

and an xml looking like this:

<?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>

I just want to generate a List of ClientCredentials objects after LINQ to the given XML

I tried like this:

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();

but I get the error Reference not set to an instance of an object.

推荐答案

You need Descendants("user") instead of Descendants("users"). Your username,password and rights elements are child element of your user elements. not Users element.That's why you are getting NullReferenceException.Also you can use the explicit cast to avoid NullReferenceException.If any element can't be found your code will still throw exception because you are accessing Value property directly.

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();

其他推荐答案

Here is a LINQ query that is expressed using query syntax. And rather than making use of the Descendants() method, the query incorporates a direct path to the elements of interest via 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")
        };

To demonstrate this query, I created a program with the sample XML data that you supplied. Also, you asked whether a missing element would generate an exception. As @Selman22 indicated, you can avoid an exception from a missing element by dropping the .Value property and using the (string) cast. Doing so will result in a empty string being returned for a missing element. To show this, I added a third <user> element and omitted its <rights> child element.

Please see below for the formatted output from my demonstration program followed by the program itself.

Demonstration Program Output

UserName:[playerone]
Password:[654321]
Rights:[true]
--
UserName:[amoreroma]
Password:[123456789]
Rights:[false]
--
UserName:[norights]
Password:[20140215]
Rights:[]
--

Demonstration Program

Note that I dropped ToList() at the end of the query expression since it isn't needed here. (This means that query is simply IEnumerable.)

using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

class ClientCredentialsDemo
{
    static public void Main(string[] args)
    {
        XDocument document = XDocument.Parse(GetXml());

        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")
                };

        foreach (var cc in query)
        {
            Console.WriteLine
                ("UserName:[{0}]\nPassword:[{1}]\nRights:[{2}]\n--",
                     cc.UserName,
                     cc.Password,
                     cc.Rights);
        }
    }

    static string GetXml()
    {
        return
            @"<?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>
                <user>
                    <username>norights</username>
                    <password>20140215</password>
                </user>
              </users>";
    }
}

public class ClientCredentials
{
    public string UserName { get; set; }
    public string Password { get; set; }
    public string Rights { get; set; }
}