Trier + Filtrer ses nœuds Xml
+ utiliser des paramètres tout cela dans les expressions XPath
I - Tri
1 - Trie sur un XmlElement Texte > XmlDataType.Text
XPathDocument oXPathDocument = new XPathDocument(System.IO.Path.Combine(Environment.CurrentDirectory, "Contacts.xml")); XPathNavigator oXPathNavigator = oXPathDocument.CreateNavigator(); XPathExpression oXPathExpression = oXPathNavigator.Compile("/Contacts/Contact"); oXPathExpression.AddSort("FirstName", XmlSortOrder.Descending, XmlCaseOrder.None, "", XmlDataType.Text); XPathNodeIterator oXPathNodeIterator = oXPathNavigator.Select(oXPathExpression); while (oXPathNodeIterator.MoveNext()) { listBox1.Items.Add(oXPathNodeIterator.Current.Value); } |
2 - Trie sur un XmlElement nombre > XmlDataType.Number
XPathDocument oXPathDocument = new XPathDocument(System.IO.Path.Combine(Environment.CurrentDirectory, "Contacts.xml")); XPathNavigator oXPathNavigator = oXPathDocument.CreateNavigator(); // XPathExpression XPathExpression oXPathExpression = oXPathNavigator.Compile("/Contacts/Contact"); oXPathExpression.AddSort("Other/Age", XmlSortOrder.Ascending, XmlCaseOrder.None, "", XmlDataType.Number); XPathNodeIterator oXPathNodeIterator = oXPathNavigator.Select(oXPathExpression); while (oXPathNodeIterator.MoveNext()) { listBox1.Items.Add(oXPathNodeIterator.Current.Value); } |
3 - Tri sur Attribut
XPathDocument oXPathDocument = new XPathDocument(System.IO.Path.Combine(Environment.CurrentDirectory, "Contacts.xml")); XPathNavigator oXPathNavigator = oXPathDocument.CreateNavigator(); // XPathExpression XPathExpression oXPathExpression = oXPathNavigator.Compile("/Contacts/Contact"); oXPathExpression.AddSort("@ID", XmlSortOrder.Ascending, XmlCaseOrder.None, "", XmlDataType.Number); XPathNodeIterator oXPathNodeIterator = oXPathNavigator.Select(oXPathExpression); while (oXPathNodeIterator.MoveNext()) { listBox1.Items.Add(oXPathNodeIterator.Current.Value); } |
Note :
L’expression de tri est soit
> une valeur string (en fait expression XPath donnant le chemin vers élément ou attribut servant de champ de tri) exemple :
- "@ID"
- "FirstName"
- "Other/Age"
Ø Soit une XPathExpression
oXPathExpression.AddSort("@ID", XmlSortOrder.Ascending, XmlCaseOrder.None, "", XmlDataType.Number); |
Ø 2 sens de tri
- XmlSortOrder.Ascending (plus petit nombre vers le plus grand,ordre alphabétique)
- XmlSortOrder.Descending
Ø Respect de la casse des caractères
Ø La prise en charge de la langue
Ø 2 types de valeurs XmlDataType.Text et XmlDataType.Number
II Des paramètres dans ses expressions XPath
Pendant que j’y suis , on peut utiliser des paramètres dans ses expressions XPath un peu comme ce que l’on fait avec les bases de données … l’avantage ? entre autres cela permet d’inserer des caractères tels ‘ dans ces expressions XPath
Voila un bon lien pour mieux comprendre
il présente 3 méthodes :
- la classique avec string.Format
- une utilisant les variables Xslt
- une utilisant Mvp.xml (projet disponible sur CodePlex) > http://www.codeplex.com/MVPXML Un merci aussi à Bidou de CodeS-SourceS grace à qui j’ai su comment trier « dans les règles » une collection de nœuds Xml
Donc la conclusion est simple :
On peut à la fois filtrer les noeuds grace aux expressions XPath (avec utilisation même de paramètres)
mais également trier
(et même ajouter/supprimer bien sur des nœuds au cours de l’iteration de XPathNodeIterator)
Ce qui donnerait pour exemple (filtre et tri + variables)
public System.Collections.IEnumerable GetContacts(string FirstName) { XPathExpression oXPathExpression = System.Xml.XPath.XPathExpression.Compile("/Contacts/Contact[starts-with(FirstName, $firstname)]"); CustomContext oCustomContext = new CustomContext(); oCustomContext.AddVariable("firstname", FirstName); oXPathExpression.SetContext(oCustomContext); oXPathExpression.AddSort("FirstName", XmlSortOrder.Ascending, XmlCaseOrder.None, "", XmlDataType.Text); // iteration (les noeuds sont donc ici deja filtres et triés) System.Xml.XPath.XPathNavigator oXPathNavigator = oXPathDocument.CreateNavigator(); System.Xml.XPath.XPathNodeIterator oXPathNodeIterator = oXPathNavigator.Select(oXPathExpression); while (oXPathNodeIterator.MoveNext()) { yield return oXPathNodeIterator.Current.Value; } } |
Le fichier Xml utilisé pour les exemples
<?xml version="1.0" encoding="utf-8" ?> <Contacts> <Contact ID="1"> <FirstName>eric</FirstName> <LastName>Dupond</LastName> <Gender>H</Gender> <Other> <Age>32</Age> </Other> </Contact> <Contact ID="58"> <FirstName>Jeanne</FirstName> <LastName>Dupond</LastName> <Gender>F</Gender> <Other> <Age>20</Age> </Other> </Contact> <Contact ID="30"> <FirstName>henri</FirstName> <LastName>Dumond</LastName> <Gender>H</Gender> <Other> <Age>15</Age> </Other> </Contact> <Contact ID="45"> <FirstName>Paul</FirstName> <LastName>Durand</LastName> <Gender>F</Gender> <Other> <Age>28</Age> </Other> </Contact> <Contact ID="5"> <FirstName>Luc</FirstName> <LastName>D'urand</LastName> <Gender>H</Gender> <Other> <Age>19</Age> </Other> </Contact> </Contacts> |
Et finalement Linq ne devient pas forcement necessaire, surtout que je me rends compte que Linq n’est pas dans tous les cas une avancée, mais la souplesse qu’il apporte dans la sélection des données est quand même très intéressante