簡體   English   中英

如何檢查WCF配置文件中的兩個XML元素在功能上是否等效?

[英]How to check if two XML elements in a WCF configuration file are functionally equivalent?

我想編寫代碼以編程方式修改.NET配置文件的WCF部分。 具體來說,我希望能夠檢查是否存在某種特定類型的綁定,如果不存在,則將其添加。 但是,檢查現有綁定確實有些棘手。

要檢查兩個綁定(或通常兩個配置元素)是否相同,請遵循以下規則:

  1. 它們必須具有相同的元素名稱(例如, <binding>不等同於<behavior>
  2. 它們可能具有不同的名稱屬性(例如,如果其他所有條件都相同,則<binding name="MyBinding">等效於<binding name="YourBinding">
  3. 所有其他屬性必須具有相同的名稱和值,並且一個元素中的每個屬性都必須存在於另一個元素中。
  4. XML注釋將被忽略
  5. 所有子元素在兩個方向上都必須在比較元素中具有等效的元素。 因此,左側的每個子元素在右側都必須具有一個等效項,反之亦然。
  6. 子元素可能以不同的順序出現。 這對兩個元素是否相等沒有影響。

我想出了以下代碼,看起來有些蠻力:

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;
}

有沒有更簡單的方法可以做到這一點?

如果您想嘗試一下,這里有一些測試用例的小提琴

如果您需要檢查除名稱以外的所有內容是否相等,那么建議您為兩個元素設置相同的名稱,並使用類似XNode.DeepEquals()的名稱。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM