2009-06-09 9 views
9

Tengo un XElement que se asigna como sigue:Ordenación de un 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> 

¿Cómo puedo ordenar los libros por autor o título o año? Gracias

Respuesta

12

¿Desea leer (consultar) los datos en un orden específico, o en realidad desea reordenar los datos en el xml? Para leer en un orden específico, sólo tiene que utilizar el método de 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") 
       }; 

(editado) Cambiar el xml es más difícil ... tal vez algo como:

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

Solo quiero reordenarlo. podrías dar un ejemplo del mundo real? – pistacchio

10

Es factible, pero un poco extraño:

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

tenga en cuenta que si usted tiene otro tipo de contenido bajo su nodo raíz, debe llamar Remove en cada XElement antes de añadirlos, en lugar de llamar RemoveAll.

+1

Maldición, estaba escribiendo esto ... ¡Me han disparado Skeet! – jfar

+0

Tenga en cuenta que las claves que se ordenan solo se analizan una vez. En su ejemplo, me preocupaba que int.Parse (yearString) se invocara dos veces para cada comparación dentro del quicksort, pero parece que las claves están previamente analizadas por EnumerableSorter.ComputeKeys(). – redcalx

+0

@BrianRogers: Buena llamada - hecho. –