How to generate array of objects after LINQ to xml in C#

假装没事ソ 提交于 2019-12-24 08:13:02

问题


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.


回答1:


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



回答2:


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


来源:https://stackoverflow.com/questions/21798570/how-to-generate-array-of-objects-after-linq-to-xml-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!