Récupérer une valeur avec Xpath

Résolu
peug Messages postés 232 Date d'inscription mercredi 25 octobre 2000 Statut Membre Dernière intervention 5 octobre 2012 - 29 juil. 2009 à 18:34
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 - 4 août 2009 à 12:57
Bonjour,

Je ne parviens pas à récupérer une valeur dans une fichier XML. Je m'embrouille. Par exemple récupérer juste la valeur de "ProposalType" :



<ShowCaption>Vrai</ShowCaption>
0
1


<DateToDo>00:00:00</DateToDo>
...

Voici mon code :

XPathDocument XPathDocu = new XPathDocument(Fichier);
XPathNavigator Navigator;
XPathNodeIterator Nodes;

Navigator = XPathDocu.CreateNavigator();

ExpXPath = "/PROPOSALS";
Nodes = Navigator.Select(Navigator.Compile(ExpXPath));
if (Nodes.Count == 1)
{

ExpXPath = "//PROPOSAL[ProposalType!='']";
Nodes = Navigator.Select(Navigator.Compile(ExpXPath));
if (Nodes.Count == 1)
{
Nodes.MoveNext();
Nodes.Current.MoveToFirstChild();
Console.WriteLine("{0}", Nodes.Current.Value);// là ca coince !
}
} else
{
MessageBox.Show("Ce n'est pas un fichier XML correcte.");
return;
}


merci de votre aide.

18 réponses

cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
2 août 2009 à 22:50
Bonsoir,
Essayes ceci:


public class Program
    {
        public static void Main(string[] args)
        {
            XPathDocument xPathDocu = new XPathDocument("test.xml");
            XPathNavigator navigator = xPathDocu.CreateNavigator();

            string xPathExpr = "//CONTENT[@Code='T1' or @Code='T2' or @Code='T3']";
            XPathNodeIterator nodes = navigator.Select(navigator.Compile(xPathExpr));

            while (nodes.MoveNext())
            {
                string str1 = nodes.Current.GetAttribute("Code", String.Empty);
                nodes.Current.MoveToFirstChild();
                string str2 = nodes.Current.InnerXml;
                Console.WriteLine(str1 + " " + str2);
            }
        }
    }



Bon début de semaine


[hr]
-Blog-
-Site Perso-
3
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
3 août 2009 à 22:01
           while (nodes.MoveNext())
            {
                string str1 = nodes.Current.GetAttribute("Code", String.Empty);
                nodes.Current.MoveToFollowing("Hours", String.Empty);
                string str2 = nodes.Current.InnerXml;
                Console.WriteLine(str1 + " " + str2);
            }


[hr]
-Blog-
-Site Perso-
3
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
29 juil. 2009 à 23:11
Bonsoir,
Tu peux jeter un oeil à:
http://www.csharpfr.com/tutorial.aspx?ID=536


[hr]
-Blog-
-Site Perso-
0
peug Messages postés 232 Date d'inscription mercredi 25 octobre 2000 Statut Membre Dernière intervention 5 octobre 2012
30 juil. 2009 à 07:16
excellent merci je pense que je vais apprendre beaucoup avec ton tuto !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
peug Messages postés 232 Date d'inscription mercredi 25 octobre 2000 Statut Membre Dernière intervention 5 octobre 2012
31 juil. 2009 à 17:59
Bonjour,

Dans ce principe :

ExpXPath = "//PROPOSAL[@Number=='200704010']";
Nodes = Navigator.Select(Navigator.Compile(ExpXPath));

while (i != Nodes.Count)
{
Nodes.MoveNext();
...
}

Comment dans la boucle récupérer la vauer de l'attribut ~@Number !?
Merci de votre aide
Christophe
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
31 juil. 2009 à 18:27
Ben dans ce cas, il vaut '200704010' non?
Pas sûr d'avoir compris la question...


[hr]
-Blog-
-Site Perso-
0
peug Messages postés 232 Date d'inscription mercredi 25 octobre 2000 Statut Membre Dernière intervention 5 octobre 2012
31 juil. 2009 à 18:29
oui tu as raison mon exemple explique mal , revoici :

ExpXPath = "//PROPOSAL[@Code='T1' or @Code='T2']";

Mais il peut y avoir d'autre attribut que je souhaite utiliser dans la boucle While. Alors comment les récupérer avec le Nodes ?
0
peug Messages postés 232 Date d'inscription mercredi 25 octobre 2000 Statut Membre Dernière intervention 5 octobre 2012
31 juil. 2009 à 18:44
Voici ce que j'ai fait : BON NE ME TAPEZ PAS car cela fait qu'une semaine que je découvre C# et l'xml. Vendredi dernier j'étais encore avec mon VB6.


<CONTENTS>
<CONTENT ART="" Code="T2">
<Texte>sous-titre</Texte>
...

XPathNodeIterator Nodes2;
ExpXPath = "//CONTENT[@Code='T1' or @Code='T2' or @Code='T3']";
Nodes = Navigator.Select(Navigator.Compile(ExpXPath));

String t = "";
treeView1.Nodes.Clear();
treeView1.BeginUpdate();

while (Nodes.MoveNext())
{
/* Je déclare et on crée une instance des variables */
StructureTitle.cTitle oTitle = new StructureTitle.cTitle();

//Je clone Nodes sur Nodes 2 et me déplace dans Nodes2 sans emmerder La position sur Nodes
Nodes2 = Nodes.Clone();
Nodes2.Current.MoveToFirstAttribute(); // se place au début
Nodes2.Current.MoveToNextAttribute(); // et now pile sur Code
t = Nodes2.Current.Value;
oTitle.OutlineLevel = Int32.Parse(t.Replace("T", "").ToString());

Nodes.Current.MoveToFirstChild();
treeView1.Nodes.Add(Nodes.Current.Value);


oTitle.Name = Nodes.Current.Value;
listTitle.Add(oTitle);
}



il me parait plus qu'évident que j'ai fait une grosse bidouille hyper nono optimiser. Pour le moment ca marche mais .....
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
31 juil. 2009 à 19:08
HA oui je vois. Me rappelle plus exactement les noms des méthodes, mais y'en a une qui doit s'appeller GetAttribute(string ns, string name) ou qqch de similaire.


[hr]
-Blog-
-Site Perso-
0
peug Messages postés 232 Date d'inscription mercredi 25 octobre 2000 Statut Membre Dernière intervention 5 octobre 2012
31 juil. 2009 à 19:31
oui mais non,
Je suis plus à mon ordi de dév mais
Dans la boucle Nodes.current.GetAttbitute("Code").Value ne renvoi pas la valeur car le Nodes est un égale à InnerXml
J'ai pensé aussi à faire un selecSimpleNode avec le Nodes.OuterXml mais ce dernier est un string me semble t il.

Bref, un fois avec le résultat de Nodes = Navigator.Select(Navigator.Compile(ExpXPath));
plus moyen d'acceder facilement aux attributs
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
31 juil. 2009 à 19:52
Ca doit marcher, faut juste être positionné au bon endroit quand l'appelle est fait...
Si tu peux fournir un petit fichier XML avec un bout de code, ca sera plus simple, car j'ai rien pour tester.
Bon week end.


[hr]
-Blog-
-Site Perso-
0
peug Messages postés 232 Date d'inscription mercredi 25 octobre 2000 Statut Membre Dernière intervention 5 octobre 2012
31 juil. 2009 à 20:18
oui, je ferai un copier coller du petit XML et du code précis si tu veux. Bon WE à toi.
0
peug Messages postés 232 Date d'inscription mercredi 25 octobre 2000 Statut Membre Dernière intervention 5 octobre 2012
1 août 2009 à 10:34
Bonjour,
Voici déjà un bon extrait du XML :

<?xml version="1.0" encoding="iso-8859-15"?>


63,917


<CONTENTS>
<CONTENT ART="2" Code= "44">
<Texte>Lorem ipsum dolor sit amet consectetuer vel condimentum.</Texte>

<Hours>2,2</Hours>
</CONTENT>
<CONTENT ART ="" Code="T1">
<Texte>PLAFOND FIBRE MINERALE</Texte>
</CONTENT>
<CONTENT ART="1" Code="43">
<Texte>Lorem ipsum dolor sit amet consectetuer vel condimentum.</Texte>
<Quantity>24,9</Quantity>
<MontantHT>73,73</MontantHT>
<Hours>12,45</Hours>
</CONTENT>
<CONTENT ART="" Code="T2">
<Texte>sous-titre</Texte>
</CONTENT>
<CONTENT ART="3" Code="42">
<Texte>Lorem ipsum dolor sit amet consectetuer vel condimentum.</Texte>
<Quantity>34,2</Quantity>
<MontantHT>80,32</MontantHT>
<Hours>17,1</Hours>
</CONTENT>
<CONTENT ART="4" Code="41">
<Texte>Lorem ipsum dolor sit amet consectetuer vel condimentum.</Texte>
<Quantity>35,7</Quantity>
<MontantHT>62,79</MontantHT>
<Hours>17,85</Hours>
</CONTENT>
<CONTENT ART="" Code="T2">
<Texte>Sous-titre 2</Texte>
</CONTENT>
<CONTENT ART="5" Code="45">
<Texte>Lorem ipsum dolor sit amet consectetuer vel condimentum.</Texte>
<Quantity>22</Quantity>
<MontantHT>12,2</MontantHT>
<Hours>11</Hours>
</CONTENT>
<CONTENT ART="6" Code="46">
<Texte>Lorem ipsum dolor sit amet consectetuer vel condimentum.</Texte>
<Quantity>22,4</Quantity>
<MontantHT>11,86</MontantHT>
<Hours>11,2</Hours>
</CONTENT>
</CONTENTS>
0
peug Messages postés 232 Date d'inscription mercredi 25 octobre 2000 Statut Membre Dernière intervention 5 octobre 2012
1 août 2009 à 10:41
Concernant le code, je ne sais pas trop comment/quoi donner alors voici ce qui me semble utile :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Xml;
using System.Xml.XPath;


puis dans un bouton :

XPathDocument XPathDocu = new XPathDocument("fichier.xml");
XPathNavigator Navigator;
XPathNodeIterator Nodes;

Navigator = XPathDocu.CreateNavigator();


XPathNodeIterator Nodes2;
ExpXPath = "//CONTENT[@Code='T1' or @Code='T2' or @Code='T3']";
Nodes = Navigator.Select(Navigator.Compile(ExpXPath));

String t = "";

while (Nodes.MoveNext())
            {

                Nodes2 = Nodes.Clone();
                Nodes2.Current.MoveToFirstAttribute(); // se place au début
                Nodes2.Current.MoveToNextAttribute(); // et now pile sur Code
                t = Nodes2.Current.Value;
                Console.WriteLine("{0}", "niveau=" + Int32.Parse(t.Replace("T", "").ToString()));

                Nodes.Current.MoveToFirstChild();
                Console.WriteLine("{0}", "Nom=" + Nodes.Current.Value);
            }


Voila, j'espère qu'il y a ce qui faut !?
0
peug Messages postés 232 Date d'inscription mercredi 25 octobre 2000 Statut Membre Dernière intervention 5 octobre 2012
3 août 2009 à 07:14
Bonjour !
Wwouah.
Et bien merci ! C'est si simple et j'en ai tellement ch.é. et déjà je zappé le "String.Empty" de GetAttribute
Encore Merci !!! Bonne semaine à toi aussi
0
peug Messages postés 232 Date d'inscription mercredi 25 octobre 2000 Statut Membre Dernière intervention 5 octobre 2012
3 août 2009 à 10:27
Dans le code
nodes.Current.MoveToFirstChild();

cela se déplace au premier element qui est ici <Texte> qui nous interesse.
<CONTENT ART="4" Code="41"> 
<Texte>Lorem ipsum</Texte> 
<Quantity>35.7</Quantity> 
<MontantHT>62.79</MontantHT> 
<Hours>17.85</Hours> 
</CONTENT> 

Existe-t-il alors un moyen pour atteindre un élement précis ? Si je souhaite allez lire <Hours>, dois-je donc placer autant de nodes.Current.MoveNext(); ?
Car MoveNext est bon si l'XML respecte un ordre dans le cas ou l'XML est fait n'importe comment ca ne fonctionne plus
0
peug Messages postés 232 Date d'inscription mercredi 25 octobre 2000 Statut Membre Dernière intervention 5 octobre 2012
4 août 2009 à 08:46
Ca semble si facile (pour toi) merci!
Promis, je vais me forcer à ne plus t'embêter !
0
cs_Bidou Messages postés 5487 Date d'inscription dimanche 4 août 2002 Statut Membre Dernière intervention 20 juin 2013 61
4 août 2009 à 12:57
Si jamais tu as d'autres questions, créer un nouveau topic, je ne reviendrai plus sur celui-ci.
Bonne chance pour la suite!


[hr]
-Blog-
-Site Perso-
0
Rejoignez-nous