按XAttribute值合并XDocuments:查找未合并的List<XElement>
解决未添加到目标XDocument的List查找问题
听起来你已经搞定了同Principal属性的SecurityPrivilege元素合并,但现在卡在找不到那些没被加入目标XDocument的元素上对吧?我来给你捋捋两种常见场景的解决办法:
情况1:找出整个未被添加的SecurityPrivilege元素
如果你的问题是列表里的某些SecurityPrivilege元素完全没被加入目标文档(比如目标里没有对应Principal的元素),可以用以下步骤:
- 先提取目标文档中已存在的所有
Principal值,存到一个哈希集合里(查询效率更高):
var existingPrincipals = targetDoc.Descendants("SecurityPrivilege") .Select(sp => (string)sp.Attribute("Principal")) .ToHashSet(StringComparer.OrdinalIgnoreCase); // 忽略大小写可选
- 从你的元素列表中筛选出
Principal不在这个集合里的元素:
var missingSecurityPrivileges = yourElementList .Where(elem => { var principal = elem.Attribute("Principal")?.Value; // 处理没有Principal属性的情况,或者Principal不在已存在集合中的情况 return string.IsNullOrEmpty(principal) || !existingPrincipals.Contains(principal); }) .ToList();
比如你提供的示例里,xml2中的user2对应的SecurityPrivilege,如果目标文档里原本没有user1之外的Principal,这个元素就会被筛选出来。
情况2:找出已合并Principal下未被添加的Privilege子元素
如果你的合并逻辑是把同Principal下的Privilege子元素合并,但有些Privilege没被成功加入,那需要对比每个Privilege的唯一标识(通常是Type、AccessType、Action加上权限内容的组合):
var unmergedPrivileges = new List<XElement>(); foreach (var sourceSp in yourElementList) { var principal = (string)sourceSp.Attribute("Principal"); // 找到目标文档中对应Principal的SecurityPrivilege var targetSp = targetDoc.Descendants("SecurityPrivilege") .FirstOrDefault(sp => string.Equals((string)sp.Attribute("Principal"), principal, StringComparison.OrdinalIgnoreCase)); if (targetSp == null) { // 整个SecurityPrivilege都没被添加,所有子Privilege都算未合并 unmergedPrivileges.AddRange(sourceSp.Descendants("Privilege")); continue; } // 提取目标中已存在的Privilege的唯一标识 var existingPrivilegeKeys = targetSp.Descendants("Privilege") .Select(p => $"{p.Attribute("Type")}|{p.Attribute("AccessType")}|{p.Attribute("Action")}|{p.Value.Trim()}") .ToHashSet(StringComparer.OrdinalIgnoreCase); // 筛选出源中存在但目标中没有的Privilege var missingPrivs = sourceSp.Descendants("Privilege") .Where(p => { var key = $"{p.Attribute("Type")}|{p.Attribute("AccessType")}|{p.Attribute("Action")}|{p.Value.Trim()}"; return !existingPrivilegeKeys.Contains(key); }) .ToList(); unmergedPrivileges.AddRange(missingPrivs); }
你可以根据实际业务调整Privilege的唯一标识规则,比如如果某些属性不需要参与判断,直接去掉即可。
内容的提问来源于stack exchange,提问作者fota666
相关产品推荐
相关产品推荐

