简体   繁体   中英

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM