2012-04-30 55 views
1

Linq to XML相當新穎如何刪除xml節點(遞歸使用關係)和保存該文檔。使用Linq to XML遞歸地刪除xml節點

xml的結構不能改變,因爲它來自service.Below是來自任務服務的xml。每個任務都可以嵌套任務,可能有一個或多個嵌套任務。嵌套的目的是達到N level

  • 當使用linq到XML刪除父任務之一我該如何刪除它的所有孩子?

  • 我如何知道所有成功刪除的節點?

XML:

<Tasks> 
    <Task ID="1">Clean the Room</Task> 
    <Task ID="2">Clean the Closet</Task> 
    <Task ID="3" ParentId="2">Remove the toys</Task> 
    <Task ID="4" ParentId="3">Stack action Figures on Rack</Task> 
    <Task ID="5" ParentId="3">Put soft toys under bed</Task> 
</Tasks> 

在當taskId=2被去除上面的XML,它的子任務即Id = 3應該被刪除。由於3被刪除,它的子任務45也應該被刪除。

+0

我不明白你的結構。你聲明如果'Task = 1','2,3,4,5'應該被移除,但他們都沒有'ParentID = 1'。你是不是指'Task = 2'? –

+0

@ErikPhilips對此感到抱歉。任務通過parentid屬性與另一個任務相關。因此,當具有ID = 2的任務被移除時,其子節點(具有'ParentId = 2'的任務)也應該被移除。這個過程繼續下去,直到當前刪除的任務沒有節點。 – Deeptechtons

回答

4

我要去假設與XML:

<Tasks> 
    <Task ID="1">Clean the Room</Task> 
    <Task ID="2">Clean the Closet</Task> 
    <Task ID="3" ParentId="2">Remove the toys</Task> 
    <Task ID="4" ParentId="3">Stack action Figures on Rack</Task> 
    <Task ID="5" ParentId="3">Put soft toys under bed</Task> 

    <Task note="test node" /> 
    <Task ID="a" note="test node" /> 
</Tasks> 

如果Task ID=2被刪除,這裏是一個解決方案:

// tasks = XDocument.root; 

public static void RemoveTasksAndSubTasks(XElement tasks, int id) 
{ 
    List<string> removeIDs = new List<string>(); 
    removeIDs.Add(id.ToString()); 

    while (removeIDs.Count() > 0) 
    { 
    // Find matching Elements to Remove 
    // Check for Attribute, 
    // so we don't get Null Refereence Exception checking Value 

    var matches = 
     tasks.Elements("Task") 
      .Where(x => x.Attribute("ID") != null 
         && removeIDs.Contains(x.Attribute("ID").Value)); 

    matches.Remove(); 

    // Find all elements with ParentID 
    // that matches the ID of the ones removed. 
    removeIDs = 
     tasks.Elements("Task") 
      .Where(x => x.Attribute("ParentId") != null 
         && x.Attribute("ID") != null 
         && removeIDs.Contains(x.Attribute("ParentId").Value)) 
      .Select(x => x.Attribute("ID").Value) 
      .ToList(); 

    } 
} 

結果:

<Tasks> 
    <Task ID="1">Clean the Room</Task> 

    <Task note="test node" /> 
    <Task ID="a" note="test node" /> 
</Tasks> 
1

使用以下的答案

XDocument doc = XDocument.Load("task.xml"); 
var q = from node in doc.Descendants("Task") 
     let attr = node.Attribute("ID") 
     let parent = node.Attribute("ParentId") 
     where ((attr != null && attr.Value == "3") || (parent != null && parent.Value == "3")) 
     select node; 
q.ToList().ForEach(x => x.Remove()); 
doc.Save("output.xml"); 
+0

我認爲這會刪除'ID = 1'的'Task'節點,這不是我要求的。由於ID = 1的任務被刪除,我如何刪除它的依賴任務?具有'parentId = 1'的任務以及具有父id等於parentId ='1'任務的任務?得到它 – Deeptechtons

+0

我已經編輯了他的回答,以便在where linq中比較父id屬性。此外,dere需要是父母ID屬性的空檢查 – Akanksha

+0

已編輯答案 –