2012-02-10 60 views
-2

我試圖用文件內的attribut「nil = true」來清理Xml元素。 我想出了這個算法,但我不喜歡它的外觀。用attribut「nil = true」清理Xml元素 - 創建linq版本?

有人知道這個算法的linq版嗎?

/// <summary> 
    /// Cleans the Xml element with the attribut "nil=true". 
    /// </summary> 
    /// <param name="value">The value.</param> 
    public static void CleanNil(this XElement value) 
    { 
     List<XElement> toDelete = new List<XElement>(); 

     foreach (var element in value.DescendantsAndSelf()) 
     { 
      if (element != null) 
      { 
       bool blnDeleteIt = false; 
       foreach (var attribut in element.Attributes()) 
       { 
        if (attribut.Name.LocalName == "nil" && attribut.Value == "true") 
        { 
         blnDeleteIt = true; 
        } 
       } 
       if (blnDeleteIt) 
       { 
        toDelete.Add(element); 
       } 
      } 
     } 

     while (toDelete.Count > 0) 
     { 
      toDelete[0].Remove(); 
      toDelete.RemoveAt(0); 
     } 
    } 
+3

你的問題沒有提及任何有關XML命名空間的內容,但http://www.w3.org/2001/XMLSchema-instance命名空間(通常使用前綴「xsi」)具有一個「nil」屬性,您可以將其設置爲「true」 。如果這是您使用的屬性,它解釋了爲什麼答案不能按預期工作。答案在默認名稱空間中查找'nil'屬性,並且不適用於您的XML。 – 2012-02-10 15:53:21

回答

1

有什麼nil屬性的命名空間?把裏面{}這樣的:

public static void CleanNil(this XElement value) 
{ 
    value.Descendants().Where(x=> (bool?)x.Attribute("{http://www.w3.org/2001/XMLSchema-instance}nil") == true).Remove(); 
} 
0

這應該工作..

public static void CleanNil(this XElement value) 
{ 
    var todelete = value.DescendantsAndSelf().Where(x => (bool?) x.Attribute("nil") == true); 
    if(todelete.Any()) 
    { 
     todelete.Remove(); 
    } 
} 
+0

抱歉不起作用! – frankyt79 2012-02-10 13:40:37

+0

你有什麼錯誤? – Flowerking 2012-02-10 13:48:21

0

擴展方法:

public static class Extensions 
{ 
    public static void CleanNil(this XElement value) 
    { 
     value.DescendantsAndSelf().Where(x => x.Attribute("nil") != null && x.Attribute("nil").Value == "true").Remove(); 
    } 
} 

使用範例:

File.WriteAllText("test.xml", @" 
       <Root nil=""false""> 
        <a nil=""true""></a> 
        <b>2</b> 
        <c nil=""false""> 
         <d nil=""true""></d> 
         <e nil=""false"">4</e> 
        </c> 
       </Root>"); 
var root = XElement.Load("test.xml"); 
root.CleanNil(); 
Console.WriteLine(root); 

輸出:

<Root nil="false"> 
    <b>2</b> 
    <c nil="false"> 
    <e nil="false">4</e> 
    </c> 
</Root> 

如您所見,節點<a><d>按預期方式移除。唯一要注意的事情是,你不能調用<Root>節點上的這種方法,因爲根節點不能被刪除,你會得到這個運行時錯誤:

The parent is missing.

+0

抱歉不起作用! – frankyt79 2012-02-10 13:40:42

+0

@ frankyt79你是什麼意思,它不起作用?我爲答案添加了一個工作示例。我測試了它,它工作。 – Meysam 2012-02-10 15:40:15

0

我改變我的方式來解決這一問題,並避免在我的空類型 創建無我用下面的

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer%28v=vs.90%29.aspx

public class OptionalOrder 
    { 
     // This field should not be serialized 
     // if it is uninitialized. 
     public string FirstOrder; 

     // Use the XmlIgnoreAttribute to ignore the 
     // special field named "FirstOrderSpecified". 
     [System.Xml.Serialization.XmlIgnoreAttribute] 
     public bool FirstOrderSpecified; 
    }