lok*_*wal 4 c# xml linq linq-to-xml
我正在尝试使用 LINQ 获取不同值的字典。我试过用这个:
var roleRefList =
xDocument.Root.Descendants()
.Where(x => x.Name.LocalName.Equals("roleRef") &&
!string.IsNullOrEmpty(Convert.ToString(x.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")))) &&
!string.IsNullOrEmpty(Convert.ToString(x.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")))))
.Select(l => new {
roleUri = l.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")).Value,
href = l.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")).Value
})
.Distinct()
.ToDictionary(a => a.roleUri);
Run Code Online (Sandbox Code Playgroud)
这里的问题是,当有重复的条目时,roleUri就会发生错误。我正在解析 XML 文档并制作 xElement 属性的字典,roleUri以及roleref它们是否存在于 xElement 中。
另一种解决方法是使用 for 循环:
Dictionary<string, string> roleRefList = new Dictionary<string, string>();
foreach (XElement element in xDocument.Root.Descendants().Where(x => x.Name.LocalName.Equals("roleRef")))
{
string roelUri = Convert.ToString(element.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")));
string href = Convert.ToString(element.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")));
if (!string.IsNullOrEmpty(roelUri) && !string.IsNullOrEmpty(href) && !roleRefList.ContainsKey(roelUri))
{
roleRefList.Add(roelUri, href);
}
}
Run Code Online (Sandbox Code Playgroud)
但我想使用 LINQ 来实现这一点。
您可以编写自己的Distinct方法Func<T,TKey>作为参数。您可以在此处找到示例:基于 LINQ 中任意键的不同对象列表
使用该方法,您应该能够编写:
var roleRefList = xDocument.Root.Descendants().Where(x => x.Name.LocalName.Equals("roleRef") && !string.IsNullOrEmpty(Convert.ToString(x.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")))) && !string.IsNullOrEmpty(Convert.ToString(x.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")))))
.Select(l => new
{
roleUri = l.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")).Value,
href = l.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")).Value
}).Distinct(l => l.roleUri).ToDictionary(a => a.roleUri);
Run Code Online (Sandbox Code Playgroud)
更新
或者您可以使用分组:
var roleRefList = xDocument.Root.Descendants().Where(x => x.Name.LocalName.Equals("roleRef") && !string.IsNullOrEmpty(Convert.ToString(x.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")))) && !string.IsNullOrEmpty(Convert.ToString(x.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")))))
.Select(l => new
{
roleUri = l.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("roleURI")).Value,
href = l.Attributes().FirstOrDefault(a => a.Name.LocalName.Equals("href")).Value
})
.GroupBy(l => l.roleUri)
.ToDictionary(g => g.Key, g => g.FirstOrDefault());
Run Code Online (Sandbox Code Playgroud)