2009-06-09 26 views
9

Tôi có một XElement mà các bản đồ như sau:Sorting một XElement

<book> 
    <author>sadfasdf</author> 
    <title>asdfasdf</title> 
    <year>1999</year> 
</book> 
<book> 
    <author>asdfasdf</author> 
    <title>asdfasdf</title> 
    <year>1888</year> 
</book> 
<book> 
    <author>asdfsdf</author> 
    <title>asdfasdf</title> 
    <year>1777</year> 
</book> 

Làm thế nào tôi có thể sắp xếp những cuốn sách của tác giả hoặc tiêu đề hoặc năm? Cảm ơn

Trả lời

12

Bạn có muốn đọc (truy vấn) dữ liệu theo thứ tự cụ thể hoặc bạn có thực sự muốn sắp xếp lại dữ liệu trong xml không? Để đọc theo một thứ tự cụ thể, chỉ cần sử dụng các phương pháp LINQ OrderBy:

var qry = from book in el.Elements("book") 
       orderby (int)book.Element("year") 
       select new 
       { 
        Year = (int)book.Element("year"), 
        Title = (string)book.Element("title"), 
        Author = (string)book.Element("author") 
       }; 

(chỉnh sửa) Thay đổi xml là phức tạp hơn ... có lẽ cái gì đó như:

var qry = (from book in el.Elements("book") 
       orderby (int)book.Element("year") 
       select book).ToArray(); 

    foreach (var book in qry) book.Remove(); 
    foreach (var book in qry) el.Add(book); 
+0

Tôi chỉ muốn sắp xếp lại nó. bạn có thể cung cấp một ví dụ thế giới thực? – pistacchio

10

Đó là doable, nhưng hơi kỳ quặc:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Xml.Linq; 

class Test 
{ 
    static void Main() 
    { 
     string xml = 
@"<books> 
    <book> 
    <author>sadfasdf</author> 
    <title>asdfasdf</title> 
    <year>1999</year> 
    </book> 
    <book> 
    <author>asdfasdf</author> 
    <title>asdfasdf</title> 
    <year>1888</year> 
    </book> 
    <book> 
    <author>asdfsdf</author> 
    <title>asdfasdf</title> 
    <year>1777</year> 
    </book> 
</books>"; 
     XElement root = XElement.Parse(xml); 

     List<XElement> ordered = root.Elements("book") 
      .OrderBy(element => (int)element.Element("year")) 
      .ToList(); 

     root.ReplaceAll(ordered); 
     Console.WriteLine(root); 
    } 
} 

Lưu ý rằng nếu bạn có nội dung khác theo nút gốc của bạn, bạn nên gọi Remove trên mỗi XElement trước khi thêm chúng, thay vì chỉ gọi RemoveAll.

+1

Darn, tôi vừa mới đánh máy này ... Tôi đã bị Skeet bắn tỉa! – jfar

+0

Lưu ý rằng các phím được sắp xếp trên chỉ được phân tích cú pháp một lần. Trong ví dụ của bạn, tôi đã lo ngại rằng int.Parse (yearString) sẽ được gọi hai lần cho mỗi so sánh bên trong quicksort, nhưng nó xuất hiện các khóa được phân tích cú pháp trước bởi EnumerableSorter.ComputeKeys(). – redcalx

+0

@BrianRogers: Thực hiện cuộc gọi tốt. –