You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

按XAttribute值合并XDocuments:查找未合并的List<XElement>

解决未添加到目标XDocument的List查找问题

听起来你已经搞定了同Principal属性的SecurityPrivilege元素合并,但现在卡在找不到那些没被加入目标XDocument的元素上对吧?我来给你捋捋两种常见场景的解决办法:

情况1:找出整个未被添加的SecurityPrivilege元素

如果你的问题是列表里的某些SecurityPrivilege元素完全没被加入目标文档(比如目标里没有对应Principal的元素),可以用以下步骤:

  1. 先提取目标文档中已存在的所有Principal值,存到一个哈希集合里(查询效率更高):
var existingPrincipals = targetDoc.Descendants("SecurityPrivilege")
                                 .Select(sp => (string)sp.Attribute("Principal"))
                                 .ToHashSet(StringComparer.OrdinalIgnoreCase); // 忽略大小写可选
  1. 从你的元素列表中筛选出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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:39:26