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 :

Parseur XML "intelligent"


Sujet :

C#

  1. #1
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut Parseur XML "intelligent"
    Bonjour

    Je n'ai peut etre rien compris a l'XML reader mais je ne vois pas ce qu'il apporte de fondamental par rapport a un bete streamreader !

    Mon fichier (ou flux) xml est composé d'elements de structure ci apres

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      <trace>
        <type>71</type>
        <source>Seat Leon 16-XP-XJ</source>
        <time>2008-10-15T05:55:22.0</time>
        <coordinate>
          <latitude>51.79864</latitude>
          <longitude>4.55908</longitude>
        </coordinate>
        <mileage>33690079</mileage>
        <heading>102</heading>
        <speed>0</speed>
      </trace>
    J'avais naivement imagine que le XML reader m'aurait permis une lecture structurée

    Mais si j'ai bien compris les exemple que j'ai trouvé il faut lire morceau par morceau, quand le morceau est un éléments on retiens son nom, ensuite on espere lire un text qui est la valeur et on se débrouille avec les deux
    On est pas tres loin d'un bete parsage sequentiel de fichier texte !

    J'avais au minimum espéré que le XmlReader puisse donner une liste hierarchisée d'elements du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Class Elem
    {
       object Name 
       object Value
    }
    J'ai loupé quelque chose ?
    Ou bien ce XmlReader est vraiment primitif ?

  2. #2
    Expert éminent
    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 : 46
    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
    Points : 7 660
    Points
    7 660
    Par défaut
    Le XmlReader offre une lecture de type curseur, c'est une bête lecture séquentielle. C'est adapté pour le traitement de gros fichiers XML, histoire de ne pas tout charger en mémoire. Maintenant si tu veux quelque chose de plus structuré, tu peux essayer avec une approche arbre (XmlDocument, XPathDocument pour de la lecture seule).

  3. #3
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Merci Stormimonn

    Le XmlReader offre une lecture de type curseur, c'est une bête lecture séquentielle.
    TU me rassure !
    Je croyais avoir loupé qq chose d'u peu gros !

    Par contre a l'inverse (si j'ai toujours bien compris ) XmlDocument lit tout le fichier d'un coup ....

    Il n'existe pas de Reader Natif qui parse par elément complet ?

    Mais ce que je trouve quand meme un peu gros avec le XmlReader c'est qu'il n'y a pas d'association Name / Value et que là aussi il faut bricoler séquentiellement "a la main" !!

  4. #4
    Expert éminent
    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 : 46
    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
    Points : 7 660
    Points
    7 660
    Par défaut
    Citation Envoyé par olibara Voir le message
    Par contre a l'inverse (si j'ai toujours bien compris ) XmlDocument lit tout le fichier d'un coup ....
    Oui, mais si le fichier à lire n'est pas monstrueux ça ne pose pas de problème je pense. Tu peux récupérer les éléments qui t'intéressent après. Et pour de la lecture seule il vaut mieux passer par XPathDocument, qui est optimisé à ce niveau (moins gourmand qu'un XmlDocument pour un même fichier XML).

  5. #5
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Salut

    J'ai été faire un tour du doté du XPathReader mais je ne parviens pas plus facilement a recuperer mes valeurs

    Je me suis donc retourné vers le XmlReader qui est de toute facon incontournable face a un stream !

    Aurais tu la bonté de me dire s'il n'y a pas de methode plus directe de faire ce que je fais !
    Ce serait en C, certainement pas !
    Mais en .NET Csharp je la sens mal !

    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
          reader = new XmlTextReader(doc);
     
          // Read the File
          string curName="";
          string Source = "";
          double Latitude;
          while (reader.Read())
          {
            XmlNodeType nodeType = reader.NodeType;
            switch (nodeType)
            {
              case XmlNodeType.Element:
                curName = reader.Name;
                break;
              case XmlNodeType.Text:
                if (curName.Equals("source"))
                {
                  Source = reader.Value;
                }
                else if (curName.Equals("latidude"))
                {
                  double.TryParse(reader.Value, out Latitude);
                }
                else if (// etc..)
                {
                   // etc...
                }
                break;
            }
          }

  6. #6
    Expert éminent
    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 : 46
    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
    Points : 7 660
    Points
    7 660
    Par défaut
    Citation Envoyé par olibara Voir le message
    Je me suis donc retourné vers le XmlReader qui est de toute façon incontournable face a un stream !
    Tu peux construire un XPathDocument à partir d'un objet de type Stream. Maintenant ce n'est peut être pas ce que tu entends par "stream".

    Sinon, tu peux simplifier ton code ainsi
    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
    string source = "";
    double latitude = 0;
    while (reader.Read())
    {
        switch (reader.NodeType)
        {
            case XmlNodeType.Element:
                if (reader.Name == "source")
                {
                    source = reader.ReadElementContentAsString();
                }
                else if (reader.Name == "latitude")
                {
                    latitude = reader.ReadElementContentAsDouble();
                }
                break;
        }
    }
    Cela te suffira peut être

  7. #7
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut
    Merci Stormimon

    Effectivement avec ton exemple ca simplifie un peu !

    Pour ce qui est du XpathDocument, dans mon contexte actuel ca pourrait marcher
    Mais lors de ma premiere tentative je me suis rendu compte que je devais traiter des XpathNodeIterator dont le contenu etait un innerXml et la je me suis dit que j'etais a la case depart a devoir parser un "sous" xml !


    Comme j'avais pas vraiment le temps d'analyser la situation et que je devais flater ou plus vite ce fichier XML je me suis retourné vers le XmlReader et ca roule

    Je vais encore faire mon calimero :

    A part une inflation invraissemblable de lien traitant du parsage XML, je n'ai vraiment pas trouvé un Tuto structuré bien fait, expliquant les différentes classe .NET dédiée et leur usage

    Conclusion : c'est presque plus rapide d'ecrire son propre parseur avec un streamreader que de passer des heures a chercher quel outil utiliser et la bonne maniere !

  8. #8
    Expert éminent
    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 : 46
    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
    Points : 7 660
    Points
    7 660
    Par défaut
    Voici un exemple avec XPathDocument
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    XPathDocument doc = new XPathDocument(fichierXml);
    XPathNavigator nav = doc.CreateNavigator();
     
    XPathNodeIterator itor = nav.Select("//trace");
    foreach (XPathNavigator navTrace in itor)
    {
        navTrace.MoveToFollowing("source", "");
        string source = navTrace.Value;
        navTrace.MoveToFollowing("latitude", "");
        double latitude = navTrace.ValueAsDouble;
    }
    Avec XmlDocument c'est encore plus simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(xml);
     
    foreach (XmlNode node in xmlDoc.SelectNodes("//trace"))
    {
        string source = node["source"].InnerText;
        string latitude = node["coordinate"]["latitude"].InnerText;
    }
    La différence c'est que XPathDocument ne permet que la lecture, il est donc optimisé en conséquence (en comparaison avec XmlDocument).

  9. #9
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut Ah Ah
    Merci Stormimonn

    Ca devient plus clair !

    Une chose me chipote dans ton exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    navTrace.MoveToFollowing("source", "");
    Je comprends donc que ce MoveToFollowing implique le respect de l'ordre des éléments
    Si je recois un fichier ou "latitude" se trouve avant "source" je ne trouverai jamais latidude ?

    Ou bien ce MoveToFollowing parcours un buffer circulaire ?

  10. #10
    Expert éminent
    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 : 46
    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
    Points : 7 660
    Points
    7 660
    Par défaut
    MoveToFollowing suit l'ordre du document. Maintenant, l'ordre des éléments dans un fichier XML est généralement constant, à moins de jouer de malchance

    Maintenant dans ton cas de figure, il suffirait de remonter sur le parent et de refaire une recherche.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // On se déplace vers l'élément "source"
    navTrace.MoveToFollowing("source", "");
    string source = navTrace.Value;
     
    // On remonte sur le parent pour reprendre la recherche
    // si l'ordre des éléments est inconstant
    navTrace.MoveToParent();
     
    // On se déplace vers l'élément "latitude"
    navTrace.MoveToFollowing("latitude", "");
    double latitude = navTrace.ValueAsDouble;
    Après c'est juste une gymnastique avec les Move... ^^

  11. #11
    Membre émérite
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Points : 2 498
    Points
    2 498
    Par défaut Idée cool !
    Ce qui serait vraiment cool evidement c'est d'utiliser un XpathDocument, un XpathNodeIterator

    Ca c'est pour la performance

    ET de pouvoir caster chaque element d'iterator en XmlNode !

    Ca c'est pour le confort pour utiliser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    node["coordinate"]["latitude"].InnerText
    Mais je reve sans doute !

Discussions similaires

  1. Réponses: 1
    Dernier message: 13/09/2007, 16h57

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