2010-09-12 32 views
6

Tôi cần di chuyển các nút anh chị em trước và sau một số nút nhất định. Đây là mã im làm việc vớiLINQ to XML: Cách hiệu quả nhất để di chuyển các nút lên và xuống

<tabs> 
    <tab> 
      <name>Overview</name> 
    </tab> 
    <tab> 
      <name>Testing</name> 
    </tab> 
    <tab> 
      <name>Performance</name> 
    </tab> 
    <tab> 
      <name>Braking</name> 
    </tab> 
</tabs> 

Tôi muốn di chuyển tab có kiểm tra ở trên Tổng quan. Làm thế nào tôi sẽ đi về việc này bằng cách sử dụng LINQ to XML?

+1

là gì các quy tắc cho nút anh chị em nào được di chuyển trước/sau nút nào? Hay bạn chỉ hỏi làm thế nào để di chuyển các nút xung quanh? – dtb

+0

Đó chính xác là những gì tôi cần. Tôi cần biết cách di chuyển các nút xung quanh. Cảm ơn – Luke101

Trả lời

2

Xin lỗi, đây là VB.NET và XML Literals, nhưng nó có thể được thực hiện trường học cũ trong C#. Ý tưởng ở đây là sử dụng phương pháp Reverse gia hạn:

Sub Main() 
     Dim tab = <tabs> 
         <tab> 
          <name>Overview</name> 
         </tab> 
         <tab> 
          <name>Testing</name> 
         </tab> 
         <tab> 
          <name>Performance</name> 
         </tab> 
         <tab> 
          <name>Braking</name> 
         </tab> 
        </tabs> 
     Console.WriteLine(SwapElements("Testing", "Performance", tab).ToString) 
     Console.ReadLine() 
    End Sub 
    Function SwapElements(ByVal firstElement As String, ByVal secondElement As String, ByVal tab As XElement) As XElement 
     Dim swapped = tab.Elements.Where(Function(e) e.Value = firstElement Or e.Value = secondElement).Reverse 
     Dim middle = tab.Elements.SelectMany(Function(e) e.ElementsAfterSelf.Where(Function(f) e.Value = firstElement).TakeWhile(Function(g) g.Value <> secondElement)) 
     swapped.ElementAt(0).AddAfterSelf(middle) 
     Return <<%= tab.Name %>> 
        <%= tab.Elements.Select(Function(e) e.ElementsBeforeSelf.Where(Function(f) e.Value = firstElement)) %> 
        <%= swapped %> 
        <%= tab.Elements.Select(Function(e) e.ElementsAfterSelf.Where(Function(f) e.Value = secondElement)) %> 
       </> 
    End Function 
+0

wow .. sau khi đọc nhiều lần tôi thấy rằng đây là cách thanh lịch nhất để giải quyết vấn đề này. Xin lỗi tôi đã chọn câu trả lời. Thay vào đó, tôi đã triển khai giải pháp của bạn. Cảm ơn bạn – Luke101

+0

Vui lòng trợ giúp Luke101 –

+0

Điều gì sẽ xảy ra nếu hai yếu tố không liền kề nhau? – dtb

3

Bạn có thể di chuyển các yếu tố bằng cách loại bỏ chúng và sau đó reinserting chúng vào vị trí mong muốn:

var doc = XDocument.Parse(@"<tabs>...</tabs>"); 

var tab = doc.Root.Elements().ElementAt(1); 
tab.Remove(); 
doc.Root.AddFirst(tab); 

Ngoài ra, bạn có thể tạo một tài liệu mới từ các yếu tố hiện theo thứ tự mong muốn:

var doc = XDocument.Parse(@"<tabs>...</tabs>"); 

var tabs = doc.Root.Elements(); 

var result = new XDocument(
       new XElement("tabs", 
        tabs.ElementAt(1), 
        tabs.ElementAt(0), 
        tabs.ElementAt(2))); 

tôi đã không kiểm tra nó, nhưng điều này có thể làm việc:

void Swap(XElement a, XElement b) 
{ 
    var c = new XElement("dummy"); 
    a.ReplaceWith(c); 
    b.ReplaceWith(a); 
    c.ReplaceWith(b); 
} 
+0

Tôi thực sự không quan tâm đến việc di chuyển các nút đến vị trí đầu tiên hoặc vị trí cuối cùng mà tôi chỉ muốn trao đổi các nút. Làm cách nào để trao đổi Kiểm tra và Hiệu suất nếu tab hiện tại là Thử nghiệm? – Luke101

+0

Ngoài ra, ví dụ của bạn giả định tôi biết có bao nhiêu anh chị em? Nếu tôi không biết có bao nhiêu anh chị em ruột nhưng tôi biết phần tử Thử nghiệm tồn tại ở đâu đó trong anh chị em, tôi sẽ trao đổi những yếu tố này như thế nào? – Luke101

+0

@ Luke101: Tôi đã thêm một giải pháp để hoán đổi sang XElements tùy ý trong một XDocument. Tôi đã không thử nghiệm nó mặc dù. – dtb

1

Bạn có thể sử dụng một cái gì đó như:

var tests = from node in doc.Descendants("name") where node.Value == "Testing" select node; 
    var test = tests.Single(); 
    var tab = test.Parent; 
    var tabs = tab.Parent; 
    tab.Remove(); 
    tabs.AddFirst(tab); 

Không chắc có bao nhiêu cấu trúc XML của bạn là cố định/tiếng.

+0

Tôi tin rằng mã này di chuyển thử nghiệm đến vị trí đầu tiên. Bây giờ làm thế nào tôi sẽ di chuyển thử nghiệm trao đổi và hiệu suất? tôi thực sự không thú vị trong việc di chuyển các nút đến địa điểm linh sam hoặc vị trí cuối cùng mà tôi chỉ muốn trao đổi các nút. Điều này có thể giải quyết như thế nào? – Luke101

1

Tôi biết bài này là cũ, nhưng tôi đã đưa ra cùng một vấn đề ngày hôm nay và kết thúc giải quyết nó theo cách này:

private void SwapXNodes(bool up, int inUniqueID) 
    { 
     XElement currNode = DocumentManager.xMainDocument.XPathSelectElement("//*[@UniqueID='" + inUniqueID + "']"); // find 

     if (up) 
     { 
      if (currNode.PreviousNode != null) 
      { 
       XElement xPrevious = new XElement((XElement)currNode.PreviousNode); // copy of previous node 

       currNode.PreviousNode.ReplaceWith(currNode); // previous node equal to me 
       currNode.ReplaceWith(xPrevious); // Now I should be equal to previous node 
      } 
     } 
     else 
     { 
      if (currNode.NextNode != null) 
      { 
       XElement xNext = new XElement((XElement)currNode.NextNode); // copy of Next node 

       currNode.NextNode.ReplaceWith(currNode); // Next node equal to me 
       currNode.ReplaceWith(xNext); // Now I should be equal to Next node copy 
      } 
     } 
    } 
Các vấn đề liên quan