IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Xml : Noeud rechercher tous les noeuds commençant par une certaine chaine


Sujet :

C#

  1. #1
    Membre Expert
    Profil pro
    Dév
    Inscrit en
    Juin 2007
    Messages
    1 165
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Dév

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 165
    Par défaut Xml : Noeud rechercher tous les noeuds commençant par une certaine chaine
    Bonjour,

    J'ai un fichier Xml comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <root>
     <busTV_06033_101_ var_22100b5_BaseNOUK20070416>
    500|00106|002GB|006ATE01|007Surface.S
    899|001200707031833
    999|001200707031833|002FIN
     
     </busTV_06033_101_var_22100b5_BaseNOUK20070416>
     <busTV_06033_101_Stylis VxInsetVar_PasInset_22100b5_BaseNOUK20070416>
    500|00106|002GB|006ATE01|007Surface.S
    510|001NIX|003   65|005+0025|0080100|0240|0250|0260|0270|0280|0290|033TAA|034J78100|03500
    511|001NIX|003   65|005+0025|0080100|0240|0250|0260|0270|0280|0290|033TAA|034J78100|03500
    519|001000|002000
    520|001000|002000
    898|0010
    899|001200707031834
    999|001200707031834|002FIN
     
     </busTV_06033_101_Stylis VxInsetVar_PasInset_22100b5_BaseNOUK20070416>
    </root>

    J'ai déjà une méthode dans une classe qui me permet de traiter toutes les données se situant entre<bus...> et </bus...>. Donc ce que j'aimerais, comme indiqué dans le titre, c'est de pouvoir accéder à tous les nœuds commençant par "bus". La partie restante du nom est à envoyer en paramètre à la méthode qui effectue le traitement. Comme ce n'est pas un nom complet, je ne peux donc pas faire de GetElementByTagName().

    Comme je débute en C#, je n'ai fait que cela pour l'instant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public void MultiBusReader(string XmlFile)
            {
                XmlDocument xmlBus = new XmlDocument();
                if (File.Exists(XmlFile))
                {
                    xmlBus.Load(XmlFile);
                    // Get a reference to the root node
                    XmlElement elmRoot = xmlBus.DocumentElement;
     
     
                }
            }
    Merci bien de votre aide.

  2. #2
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Salut
    A première vue je dira d'utiliser XPath.
    Ca donnerai quelque chose comme
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    XmlNodes[] bus = elmRoot.SelectNodes("//bus*");
    Mais j'ai pas testé et ca fait longtemps que j'ai pas fait de XPath.

  3. #3
    Membre Expert
    Profil pro
    Dév
    Inscrit en
    Juin 2007
    Messages
    1 165
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Dév

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 165
    Par défaut
    J'arrive à gérér avec Xpath comme tu l'as dit mais il me reste encore un problème . Dans certaines balises bus, les noms prennent parfois des espaces du genre "<busTV_06033_101_ var_22100b5_BaseNOUK20070416 physical machin>" et dc je n'arrive plus à utiliser Xpath car il crois que physical et machin sont des attributs . Serait-il correcte de foutre tous le fichier xml dans un string et de virer les espaces pour les balises <bus> sachant qu'ils ne prennent jamais d'attribut?

  4. #4
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    A la base c'est le fichier XML qui est mal foutu tout de même, le nom des balises fait peur. On dirait qu'il y a des infos dans le nom des balises en fait, cela veut dire qu'il faudrait des noeuds enfants avec ces infos éventuellement. Mais je suppose que tu ne peux rien y faire ?

    Sinon pour enlever les espaces, on peut faire quelque chose comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    static void Main(string[] args)
    {
        string xml =
    @"<?xml version=""1.0"" encoding=""ISO-8859-1"" ?>
    <root>
    <busTV_06033_101_ var_22100b5_BaseNOUK20070416>
    500|00106|002GB|006ATE01|007Surface.S
    899|001200707031833
    999|001200707031833|002FIN
     
    </busTV_06033_101_var_22100b5_BaseNOUK20070416>
    <busTV_06033_101_Stylis VxInsetVar_PasInset_22100b5_BaseNOUK20070416>
    500|00106|002GB|006ATE01|007Surface.S
    510|001NIX|003   65|005+0025|0080100|0240|0250|0260|0270|0280|0290|033TAA|034J78100|03500
    511|001NIX|003   65|005+0025|0080100|0240|0250|0260|0270|0280|0290|033TAA|034J78100|03500
    519|001000|002000
    520|001000|002000
    898|0010
    899|001200707031834
    999|001200707031834|002FIN
     
    </busTV_06033_101_Stylis VxInsetVar_PasInset_22100b5_BaseNOUK20070416>
    </root>";
     
        string s = Regex.Replace(xml, @"(?<=<).*?(?=>)",
            delegate(Match m)
            {
                return Regex.Replace(m.Value, @"\s+", string.Empty);
            });
     
        Console.ReadLine();
    }

  5. #5
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Eh ben, des espaces dans les nom de balises XML, on aura tout vu...
    Normalement, un vrai bon xml comme il devrait l'être, les noms des balises sont en minuscules, pas d'espaces dans le nom, le nom doit commencer par une lettre, pas de caractère spéciaux.
    De plus, les données présentes devraient être dans un CDATA pour éviter une éventuelle erreurs du parser si les données contiennent un caractère pouvant faire croire qu début ou la fin d'une balise/attribut/...

    Comme le dit StormimOn, le xml fournit est tout pourris, il manque de balise pour structurer tout ca.

    Par contre, l'expression rationnelle donnée ne me semble pas vraiment bonne.
    Si je ne me trompe pas, elle vire tout espace compris entre un "<" et un ">"
    Ce qui fait que la première ligne deviendrait

    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <?xmlversion="1.0"encoding="ISO-8859-1"?>

    Ce qui n'est pas bon. De même, si une balise comprend un attribut, il y aura erreur.
    Je ne vois pas comment, par code, on peux virer sans erreurs les espaces des noms de balise.
    Sauf peut-être en ré-écrivant un parser qui se servirai des balises fermantes pour déterminer le nom de balise dans attributs et les ré-écrire dans un un vrai XML. Mais si t'es pour écrire ton propre parser juste pour faire ca, autant en profiter pour extraire tes données directement plutôt ...

    Si tu ne peux vraiment pas aller botter les fesses de celui qui génère ce fichier "XML", je vois pas de solution propre et fiable. Désolé.

  6. #6
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Pour l'expression j'ai fait un peu vite effectivement. Avec ceci cela devrait aller mieux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    string s = Regex.Replace(xml, @"(?<=</?bus).*?(?=>)",
    puisque seules les balises commençant par bus nous intéressent et qu'elles ne possèdent pas d'attributs.

    L'idéal serait tout de même de revoir la structure du XML.

  7. #7
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Oui ca marcherai mieux je pense aussi. En supposant que les balises "busXXXX" n'ont jamais d'attributs.

    Comme tu dis, l'idéal serait vraiment de pouvoir faire revoir la structure a son auteur, m'est avis que la plupart des parser planteront lamentablement en lisant un truc pareil.
    Car je pense que quand le parser lit :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    <busTV_06033_101_ var_22100b5_BaseNOUK20070416>
    Il doit attendre comme balise fermante :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    </busTV_06033_101_>
    Du coup, c'est étonnant qu'il ne rale pas en voyant la balise fermante du nœud root, car pour lui, aucune des balises "busXXXX" n'ont été fermées.

  8. #8
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Hum, sinon, une solution un peu moins performante vu qu'elle boucle mais qui doit marcher en prenant en compte le risque de présence d'attribut.
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    string xml =
    @"<?xml version=""1.0"" encoding=""ISO-8859-1"" ?>
    <root>
    <busTV_06033_101_var_22100b5_BaseNOUK20070416>
    500|00106|002GB|006ATE01|007Surface.S
    899|001200707031833
    999|001200707031833|002FIN
     
    </busTV_06033_101_var_22100b5_BaseNOUK20070416>
    <busTV_06033_101_StylisVxInsetVar_PasInset_22100b5_BaseNOUK20070416>
    500|00106|002GB|006ATE01|007Surface.S
    510|001NIX|003   65|005+0025|0080100|0240|0250|0260|0270|0280|0290|033TAA|034J78100|03500
    511|001NIX|003   65|005+0025|0080100|0240|0250|0260|0270|0280|0290|033TAA|034J78100|03500
    519|001000|002000
    520|001000|002000
    898|0010
    899|001200707031834
    999|001200707031834|002FIN
     
    </busTV_06033_101_StylisVxInsetVar_PasInset_22100b5_BaseNOUK20070416>
     
    <!-- La balise -->
    <busXXX YYY ZZZ machin="truc">bla bla bla</busXXX YYY ZZZ>
    <!-- donnera -->
    <busXXXYYYZZZ machin="truc">bla bla bla</busXXXYYYZZZ>
    <!-- L'attribut est donc conservé -->
    </root>";
     
    // On match toutes les balise fermantes, juste les fermantes.
    MatchCollection mc = Regex.Matches(xml, "</(?<name>[^>]+)>");
    foreach (Match m in mc)
    {
    	// Le nom de la balise tel que trouvé dans sa version fermante.
    	string Value = m.Groups["name"].Value;
    	// Le même nom de balise, mais sans espaces.
    	string balise = Regex.Replace(Value, @"\s+", string.Empty);
    	// On remplace toutes les balises ouvrante par l'équivalent sans espace.
    	xml = xml.Replace("<" + Value, "<" + balise);
    	// Idem pour les fermantes.
    	xml = xml.Replace("</" + Value, "</" + balise);
    }

    Ainsi ca donnerai ceci :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <root>
     <busTV_06033_101_ var_22100b5_BaseNOUK20070416>
    500|00106|002GB|006ATE01|007Surface.S
    899|001200707031833
    999|001200707031833|002FIN
     
     </busTV_06033_101_var_22100b5_BaseNOUK20070416>
     <busTV_06033_101_Stylis VxInsetVar_PasInset_22100b5_BaseNOUK20070416>
    500|00106|002GB|006ATE01|007Surface.S
    510|001NIX|003   65|005+0025|0080100|0240|0250|0260|0270|0280|0290|033TAA|034J78100|03500
    511|001NIX|003   65|005+0025|0080100|0240|0250|0260|0270|0280|0290|033TAA|034J78100|03500
    519|001000|002000
    520|001000|002000
    898|0010
    899|001200707031834
    999|001200707031834|002FIN
     
     </busTV_06033_101_Stylis VxInsetVar_PasInset_22100b5_BaseNOUK20070416>
    </root>

    De même, la balise :
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    <busXXX YYY ZZZ machin="truc">bla bla bla</busXXX YYY ZZZ>
    Donnera
    Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
    <busXXXYYYZZZ machin="truc">bla bla bla</busXXXYYYZZZ>
    L'attribut est donc conservé.

    Limitations :
    * Sur un gros fichier xml, le code sera vite très très lent, sur ton exemple ca se passera sans problème.
    * Si jamais une balise contient en tant que donnée du xml (dans un CDATA par exemple, ou dans un commentaire) il sera traité également, ce qui peut être préjudiciable.
    * Toute occurence de "<balise avec espace" sera remplacée par "<baliseavecespace", ca peux donner lieu à des remplacement non voulu dans de rares cas.
    * La solution ne remplace en aucun cas le fait qu'il serait fortement souhaitable que le xml fournit en entré soit correcte.

  9. #9
    Membre Expert
    Profil pro
    Dév
    Inscrit en
    Juin 2007
    Messages
    1 165
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Dév

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 165
    Par défaut
    C'est bon donc en magouillant les espaces le traitement marche.

    Merci encore.


    PS : oui je n'ai pas fait ce faux XML et je n'ai pas le droit d'y toucher.

  10. #10
    Membre émérite Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Par défaut
    Si tu as contacte avec celui qui l'a fait, gueule-lui dessus fort bruyamment et dis lui de prendre des cours...

    Au passage, si tu as résolut ton problème, un petit click sur le bouton "Résolut" afin que d'autres de viennent pas pour rien

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Rechercher tous les ID commencant par
    Par kryogen dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 30/01/2008, 14h07
  2. moteur de recherche d'un nom commençant par une lettre quelquonque
    Par monphp dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 24/06/2007, 18h01
  3. [exp reguliere]Bouton "tout cocher" pour tous les id commençant par 'bvt_'
    Par boniface dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 12/06/2007, 15h58
  4. fonction recherche tous les articles commencant par *
    Par Daniel MOREAU dans le forum Access
    Réponses: 4
    Dernier message: 31/01/2007, 16h04
  5. Sélectionner tous les id renvoyés par une 1ère requête
    Par Prof Vince dans le forum Requêtes
    Réponses: 5
    Dernier message: 29/11/2003, 19h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo