C# 如何检查WCF配置文件中的两个XML元素在功能上是否等效?

C# 如何检查WCF配置文件中的两个XML元素在功能上是否等效?,c#,.net,xml,linq,C#,.net,Xml,Linq,我想编写代码以编程方式修改.NET配置文件的WCF部分。具体来说,我希望能够检查是否存在某种特定的绑定,如果不存在,则添加它。然而,检查现有绑定有点棘手 要检查两个绑定(或通常两个配置元素)是否相同,请遵循以下规则: 它们必须具有相同的元素名称(例如,不等同于) 它们可能具有不同的名称属性(例如,等同于,如果其他所有属性都相同) 所有其他属性必须具有相同的名称和值,并且一个元素中的每个属性都必须存在于另一个元素中 XML注释被忽略 所有子元素在两个方向上都必须在所比较的元素中具有等效项。因此,左

我想编写代码以编程方式修改.NET配置文件的WCF部分。具体来说,我希望能够检查是否存在某种特定的绑定,如果不存在,则添加它。然而,检查现有绑定有点棘手

要检查两个绑定(或通常两个配置元素)是否相同,请遵循以下规则:

  • 它们必须具有相同的元素名称(例如,
    不等同于
  • 它们可能具有不同的名称属性(例如,
    等同于
    ,如果其他所有属性都相同)
  • 所有其他属性必须具有相同的名称和值,并且一个元素中的每个属性都必须存在于另一个元素中
  • XML注释被忽略
  • 所有子元素在两个方向上都必须在所比较的元素中具有等效项。因此,左侧的每个子元素必须在右侧有一个等价项,反之亦然
  • 子元素可能以不同的顺序出现。这对两个元素是否相等没有影响
  • 我提出了以下代码,这似乎是蛮力的:

    static public bool IsEquivalentTo(this XElement source, XElement compareTo)
    {
        if (source == null && compareTo == null) return true;
        if (source == null || compareTo == null) return false;
        if (source.Equals(compareTo)) return true;
    
        //Compare element name
        if (source.Name != compareTo.Name) return false;
    
        //Compare all attributes except the "Name" attribute (which is different from the element's name proper)
        var attributes = source.Attributes().ToDictionary( x => x.Name, x => x.Value);
        if (attributes.Count != compareTo.Attributes().Count()) return false;
    
        foreach (var a in attributes)
        {
            if (a.Key == "name") continue;
            if (a.Value != compareTo.Attribute(a.Key).Value) return false;
        }
    
        //Compare subelements. Each element on the left must have a matching element on the right. ,and vice versa. 
        var lhs = source.Elements().ToList();
        var rhs = compareTo.Elements().ToList();
        foreach (var l in lhs)
        {
            bool found = false;
            foreach (var r in rhs)
            {
                if (l.IsEquivalentTo(r))
                {
                    found = true;
                    break;
                }
            }
            if (!found) return false;
        }
        foreach (var r in rhs)
        {
            bool found = false;
            foreach (var l in lhs)
            {
                if (r.IsEquivalentTo(l))
                {
                    found = true;
                    break;
                }
            }
            if (!found) return false;
        }
        return true;
    }
    
    有没有更简单的方法来实现这一点


    如果您想尝试一下,下面是一个包含一些测试用例的示例。

    如果您需要检查除名称之外的所有内容的相等性,那么我建议您可以为这两个元素设置相同的名称,并使用类似