代码之家  ›  专栏  ›  技术社区  ›  user2128702

如何在C语言中生成LINQ to xml之后的对象数组#

  •  1
  • user2128702  · 技术社区  · 10 年前

    我有一个这样的对象:

    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之后 到给定的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();
    

    但我得到了错误 未设置对象实例的引用 .

    2 回复  |  直到 10 年前
        1
  •  3
  •   Selman Genç    10 年前

    你需要 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();
    
        2
  •  0
  •   DavidRR    10 年前

    下面是一个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 属性,并使用 (string) 铸造这样做将导致为缺少的元素返回空字符串。为了显示这一点,我添加了第三个 <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; }
    }