Probleme pour lire un fichier xml

Probleme pour lire un fichier xml - C#/.NET managed - Programmation

Marsh Posté le 22-06-2009 à 20:37:22    

Bonjour,
 
voila ca fait 2 jours que j'essaye un peu tout pour lire le fichier xml suivant:
<DataSources>
 <DataSource>
  <Company>P</Company>
  <UnitsFiles>
   <UnitFile>
    <Unit>Metric</Unit>
    <File>rec_setup_P.dat</File>
   </UnitFile>
   <UnitFile>
    <Unit>English</Unit>
    <File>rec_setup_PEnglish.dat</File>
   </UnitFile>
   <UnitFile>
    <Unit>Mexican</Unit>
    <File>rec_setup_PMexico.dat</File>
   </UnitFile>
  </UnitsFiles>
 </DataSource>
 <DataSource>
  <Company>I</Company>
  <UnitsFiles>
   <UnitFile>
    <Unit>Metric</Unit>
    <File>rec_setup_IMetric.dat</File>
   </UnitFile>
   <UnitFile>
    <Unit>English</Unit>
    <File>rec_setup_IEnglish.dat</File>
   </UnitFile>
   <UnitFile>
    <Unit>Mexican</Unit>
    <File>rec_setup_IMexico.dat</File>
   </UnitFile>
  </UnitsFiles>
 </DataSource>
</DataSources>

Je veux recuperer les noms <Company> avec les correspondants "files" et "units".
Voila le code qui se rapproche le plus de la solution (je pense) mais je n'arrive a recuperer qu'un seul fichet et unit par company.
 
            string FileName = "C:\\HSPM\\DataSourceUnitQED.xml";
            XmlReader reader = XmlReader.Create(FileName);
 
            do{
                reader.ReadToFollowing("Company" );
                string Provider = reader.ReadInnerXml();
                List<string> Units = new List<string>();
                List<string> Files = new List<string>();
                reader.ReadToFollowing("UnitsFiles" );
                reader.ReadToFollowing("UnitFile" );
                do{
                    //get units and wits file names
                    reader.ReadToDescendant("Unit" );
                    Units.Add(reader.ReadInnerXml());
                    reader.ReadToFollowing("File" );
                    Files.Add(reader.ReadInnerXml());
                } while (reader.ReadToNextSibling("UnitFile" ));
                ProviderUnitsWitsList.Add(new ProviderUnitsWitsFiles(Provider, Units, Files));
            } while (reader.ReadToFollowing("DataSource" ));

 
Pouvez vous m'aider? Suis je dans la bonne direction?
Merci

Reply

Marsh Posté le 22-06-2009 à 20:37:22   

Reply

Marsh Posté le 23-06-2009 à 00:45:55    

Ton fichier n'est pas très pratique à parser... Il aurait été plus logique que l'élement <UnitsFile> eut été un élément enfant de l'élément <Company> au lieu d'en faire un élément de même niveau. Ca aurait rendu le parsing bien plus simple.

 

Si tu es en .NET 3.5, tu devrais utiliser LINQ to XML, qui est largement supérieur au parseur DOM d'origine. Voici ce que je te propose (en LINQ)

 
Code :
  1. XElement xml = XElement.Parse(@"<DataSources>
  2. <DataSource>
  3.  <Company>P</Company>
  4.  <UnitsFiles>
  5.   <UnitFile>
  6.     <Unit>Metric</Unit>
  7.     <File>rec_setup_P.dat</File>
  8.   </UnitFile>
  9.   <UnitFile>
  10.     <Unit>English</Unit>
  11.     <File>rec_setup_PEnglish.dat</File>
  12.   </UnitFile>
  13.   <UnitFile>
  14.     <Unit>Mexican</Unit>
  15.     <File>rec_setup_PMexico.dat</File>
  16.   </UnitFile>
  17.  </UnitsFiles>
  18. </DataSource>
  19. <DataSource>
  20.  <Company>I</Company>
  21.  <UnitsFiles>
  22.   <UnitFile>
  23.     <Unit>Metric</Unit>
  24.     <File>rec_setup_IMetric.dat</File>
  25.   </UnitFile>
  26.   <UnitFile>
  27.     <Unit>English</Unit>
  28.     <File>rec_setup_IEnglish.dat</File>
  29.   </UnitFile>
  30.   <UnitFile>
  31.     <Unit>Mexican</Unit>
  32.     <File>rec_setup_IMexico.dat</File>
  33.   </UnitFile>
  34.  </UnitsFiles>
  35. </DataSource>
  36. </DataSources>" );
  37.  
  38. // d'abord on isole les nodes
  39. IEnumerable<XElement> allNodes =     from node in xml.Nodes()
  40.                                        select node as XElement;
  41.  
  42. // puis on extrait les infos
  43. var infos = (from element in allNodes
  44.         let company = (    from companies in element.Descendants()
  45.                            where companies.Name == "Company"
  46.                            select companies.Value)
  47.         let unit = (    from units in element.Descendants()
  48.                         where units.Name == "Unit"
  49.                         select units.Value)
  50.         let files = (    from files in element.Descendants()
  51.                          where files.Name == "File"
  52.                          select files.Value)
  53.              select new
  54.              {
  55.                  c = company,
  56.                  u = unit,
  57.                  f = files
  58.              });
  59.  
  60. var infosArray = infos.ToArray();
  61.  
  62. foreach (var info in infosArray)
  63. {
  64.     Console.WriteLine("Provider : {0}", info.c.ToArray()[0]);
  65.     Console.WriteLine("--------------" );
  66.  
  67.     foreach (var unit in info.u.ToArray())
  68.     {
  69.         Console.WriteLine("Unit : {0}", unit);
  70.     }
  71.     foreach (var file in info.f.ToArray())
  72.     {
  73.         Console.WriteLine("File : {0}", file);
  74.     }
  75.     Console.WriteLine();
  76. }
 

la sortie est la suivante :

Citation :


Provider : P
--------------
Unit : Metric
Unit : English
Unit : Mexican
File : rec_setup_P.dat
File : rec_setup_PEnglish.dat
File : rec_setup_PMexico.dat

 

Provider : I
--------------
Unit : Metric
Unit : English
Unit : Mexican
File : rec_setup_IMetric.dat
File : rec_setup_IEnglish.dat
File : rec_setup_IMexico.dat

 

A toi de récupérer les infos souhaitées dans le conteneur que tu souhaites


Message édité par Harkonnen le 23-06-2009 à 01:01:53

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 23-06-2009 à 15:45:20    

Je ne peux pas utiliser Linq car je travaille avec .NET 2.0.
Aussi je ne peux pas modifier le fichier XML.

Reply

Marsh Posté le 23-06-2009 à 17:22:10    

J'ai essaye avec ReadToFollowing() mais dans ce cas ca lit tous les units and files et ne s'arrete pas entre les companies.

Reply

Marsh Posté le 24-06-2009 à 21:36:14    

Si la solution ci-dessus ne devait pas convenir, à défaut de pouvoir utiliser Linq to XML en 2.0 tu peux utiliser XPath, tu y gagnerais par rapport à ta méthode !


Message édité par TotalRecall le 24-06-2009 à 21:36:25

---------------
Réalisation amplis classe D / T      Topic .Net - C# @ Prog
Reply

Marsh Posté le 25-06-2009 à 09:07:04    

+1, c'est un moindre mal par rapport au parser DOM tout pourri


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed