使用 LINQ 从 XDocument 检索嵌套列表
本文关键字:嵌套 列表 检索 XDocument LINQ 使用 | 更新日期: 2023-09-27 18:37:26
好的,我希望我的链接查询返回用户列表。下面是 XML
<section type="Users">
<User type="WorkerProcessUser">
<default property="UserName" value="Main"/>
<default property="Password" value=""/>
<default property="Description" value=""/>
<default property="Group" value=""/>
</User>
<User type="AnonymousUser">
<default property="UserName" value="Second"/>
<default property="Password" value=""/>
<default property="Description" value=""/>
<default property="Group" value=""/>
</User>
</section>
而我当前不起作用的 LINQ 查询.doc是一个 XDocument
var users = (from iis in doc.Descendants("section")
where iis.Attribute("type").Value == "Users"
from user in iis.Elements("User")
from prop in user.Descendants("default")
select new
{
Type = user.Attribute("type").Value,
UserName = prop.Attribute("UserName").Value
});
我得到了一个Object reference not set to an instance of an object
例外。谁能告诉我我需要修复什么?
这是我修复错误属性名称后的第二次尝试。但是,当我尝试使用它或至少当我尝试将其写入控制台时,这个似乎没有为我枚举用户名值。此外,这总共返回 8 个结果,我应该只有 2 个结果,因为我只有 2 个用户。
(from iis in doc.Descendants("section")
where iis.Attribute("type").Value == "Users"
from user in iis.Elements("User")
from prop in user.Descendants("default")
select new
{
Type = user.Attribute("type").Value,
UserName = (from name in prop.Attributes("property")
where name.Value == "UserName"
select name.NextAttribute.Value).ToString()
});
我会做这样的事情:
doc.XPathSelectElement("section[@type='Users']")
.Elements("User")
.Select(c => new
{
Type = c.Attribute("type").Value,
UserName = c.XPathSelectElement("default[@property='UserName']").Attribute("value").Value
});
您需要在.cs文件的顶部添加using System.Xml.XPath;
,以便找到XPathSelectElement
扩展方法。
您的default
元素没有 username
属性,username
是 property
属性的值。
以下是您的查询应该如何作为Henk Holterman
所写内容的替代方案。不同之处在于我在User
元素级别而不是default[@property='UserName']
元素级别进行选择。
var usr = (from iis in doc.Descendants("section")
where iis.Attribute("type").Value == "Users"
from user in iis.Elements("User")
select new
{
Type = user.Attribute("type").Value,
UserName = (from prop in user.Descendants("default")
where prop.Attribute("property").Value == "UserName"
select prop.Attribute("value").Value).FirstOrDefault()
});
与第二次尝试相比,代码from prop in user.Descendants("default")
已移至匿名类型构造函数中,并且简化了对用户名的分配。
var root = XDocument.Load(@"...").Root;
var ns = root.GetDefaultNamespace();
var users = root.Descendants(ns.GetName("default")).Where(e => e.Attribute("property").Value == "UserName").Select(e => new
{
Type = e.Parent.Attribute("type").Value,
UserName = e.Attribute("value").Value
});
Console.WriteLine(String.Join(Environment.NewLine, users.Select(u => String.Format("{0} ({1})", u.UserName, u.Type))));