2009-06-09 8 views
9

J'ai un XElement qui mappe comme suit:Tri d'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> 

Comment puis-je trier les livres par auteur ou le titre ou l'année? Merci

Répondre

12

Voulez-vous lire (interroger) les données dans un ordre spécifique, ou voulez-vous réellement re-commander les données dans le xml? Pour lire dans un ordre spécifique, il suffit d'utiliser la méthode 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") 
       }; 

(modifié) Modification du xml est plus délicate ... peut-être quelque chose comme:

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

Je veux juste le réorganiser. pourriez-vous fournir un exemple du monde réel? – pistacchio

10

Il est faisable, mais un peu bizarre:

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

Notez que si vous avez un autre contenu sous votre nœud racine, vous devez appeler Remove sur chaque XElement avant de les ajouter, au lieu d'appeler RemoveAll.

+1

Darn, je tapais juste ça ... J'ai été snipé Skeet! – jfar

+0

Notez que les clés triées ne sont analysées qu'une seule fois. Dans votre exemple, je pensais que int.Parse (yearString) serait appelé deux fois pour chaque comparaison dans le quicksort, mais il semble que les clés soient pré-analysées par EnumerableSorter.ComputeKeys(). – redcalx

+0

@BrianRogers: Bon appel - fait. –