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

Format d'échange (XML, JSON...) Java Discussion :

Parser un XML sans le charger en mémoire sous forme de document [SAX]


Sujet :

Format d'échange (XML, JSON...) Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 23
    Points : 18
    Points
    18
    Par défaut Parser un XML sans le charger en mémoire sous forme de document
    Bonjour
    voila mon problème :
    Je dois lire un fichier XML qui a cette strucuture :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    <MESSAGES NbMessage="800">                          
       <MESSAGE nom="Martin" prenom ="Olivier">
    	<CONTENT><![CDATA[ bla bla bla...]]></CONTENT>
       </MESSAGE>
       <MESSAGE nom="Martin" prenom ="Michelle">
    	<CONTENT><![CDATA[ bla bla bla...]]></CONTENT>
       </MESSAGE>
    .  ...
    </MESSAGES>
    Le nombres de MESSAGE sera assez volumineux.
    Je souhaiterais parser ce fichier XML afin de faire des traitements divers à partir de l'objet MESSAGE.

    Je pensais partir sur une implémentation à partir d'un parseur DOM ou SAX, mais je me dis aussi que le chargement du fichier XML en mémoire sous forme de org.w3c.dom.Document nuirait aux performances du prog. Qu'en pensez-vous?

    Peut-etre faudrait-il partir sur l'utilisation d'un BufferedReader pour lire le fichier ligne à ligne. Mais là encore, si le fichier est mal indenté ou 2 balises sur la même ligne, j'ai une exception de type SAXException
    ex :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    <MESSAGES NbMessage="800">                          
    <MESSAGE nom="Martin" prenom ="Olivier">
    	<CONTENT><![CDATA[ bla bla bla...]]></CONTENT>
    </MESSAGE><MESSAGE nom="Martin" prenom ="Michelle">
    	<CONTENT><![CDATA[ bla bla bla...]]></CONTENT>
    </MESSAGE>
    ....
    </MESSAGES>
    Avez-vous une idée d'une solution peformante?
    Pour info, par la suite, un fois chaque bloc MESSAGE récupéré, j'utiliserais la méthode Unmarshall pour avoir un objet java MESSAGE avec les getters et setters utiles

    Merdi d'avance pour vos réponses
    @++

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 466
    Points : 1 610
    Points
    1 610
    Par défaut
    Sax est idéal dans ton cas, car il respose sur du déclanchement d'évenements (entrée/sortie d'un noeud/attribut) et donc de construire des objets java au fur à mesure.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 23
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Morbo
    Sax est idéal dans ton cas, car il respose sur du déclanchement d'évenements (entrée/sortie d'un noeud/attribut) et donc de construire des objets java au fur à mesure.
    J'utilise le org.apache.xerces.parsers.SAXParser SAXParser comme parser. Peux-tu me donner un exemple concret? il y a t-il des méthodes à surcharger pour gérer les évenements?
    Merci d'avance

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 466
    Points : 1 610
    Points
    1 610
    Par défaut
    Des exemples il y en a là : http://java.developpez.com/faq/xml/?page=sax
    Et en effet tu déclares une classe qui va surcharger les méthodes appellés lors du parsing.

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 23
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Morbo
    Des exemples il y en a là : http://java.developpez.com/faq/xml/?page=sax
    Et en effet tu déclares une classe qui va surcharger les méthodes appellés lors du parsing.
    Merci, j'ai consulté les exemples mais cela ne m'aide pas vraiment car cela revient à gérer tous les attributs et les éléments par moi-même. En fait je souhaiterais plus récupérer dans mon fichier XML un objet String

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    String monobjetCourant ="<MESSAGE nom="Martin" prenom ="Olivier"><CONTENT><![CDATA[ bla bla bla...]]></CONTENT></MESSAGE>" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    et utiliser 
    MESSAGE = msgGingerbackup = (MESSAGE )Unmarshaller.unmarshal(MESSAGEGINGER.class, new StringReader(str));

  6. #6
    Membre expérimenté
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    1 466
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 1 466
    Points : 1 610
    Points
    1 610
    Par défaut
    Ben je pense pas que tu puisses puisque pour n'en faire qu'une ligne car il faut déja avoir extrait le noeud et donc analysé la grammaire et syntaxe xml puisque tu veux gerer les cas sur plusieurs lignes.

    Sinon si t'es sur que "</MESSAGE>" est sur une ligne séparé et "<MESSAGE" en début de ligne, tu dois pouvoir créer un buffer contenant tout le message au fur et à mesure que tu lis l'inputstream et l'analyser avec jdom.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 23
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Morbo
    Ben je pense pas que tu puisses puisque pour n'en faire qu'une ligne car il faut déja avoir extrait le noeud et donc analysé la grammaire et syntaxe xml puisque tu veux gerer les cas sur plusieurs lignes.

    Sinon si t'es sur que "</MESSAGE>" est sur une ligne séparé et "<MESSAGE" en début de ligne, tu dois pouvoir créer un buffer contenant tout le message au fur et à mesure que tu lis l'inputstream et l'analyser avec jdom.
    Justement je ne suis pas sûr que "</MESSAGE>" soit sur une ligne séparé et "<MESSAGE" en début de ligne, c'est bien ca mon problème. Que penses-tu du chargement du document en mémoire niveau performance?

  8. #8
    Membre confirmé
    Inscrit en
    Mai 2007
    Messages
    335
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 335
    Points : 511
    Points
    511
    Par défaut
    Tu peux lire ligne à ligne et détecter simplement la présence des tags <MESSAGE </MESSAGE> n'importe ou dans la ligne, mais ça me semble plus fiable d'utiliser SAX:
    sur ton DefaultHandler, il suffit:
    - dans "startElement" si "Message": conserver nom-prénom démarrer un buffer, -dans "characters" ajouter au buffer,
    - dans endElement si "Message" interpréter le buffer,

    c'est assez rapide quand même?
    reste à voir comment ça interprète le CDATA.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 23
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par deltree
    Tu peux lire ligne à ligne et détecter simplement la présence des tags <MESSAGE </MESSAGE> n'importe ou dans la ligne, mais ça me semble plus fiable d'utiliser SAX:
    sur ton DefaultHandler, il suffit:
    - dans "startElement" si "Message": conserver nom-prénom démarrer un buffer, -dans "characters" ajouter au buffer,
    - dans endElement si "Message" interpréter le buffer,

    c'est assez rapide quand même?
    reste à voir comment ça interprète le CDATA.
    J'ai utilisé SAX en redéfinissant les méthodes appropriées et concernant le CDATA, le parser récupère le contenu sans les balises CDATA. Dans le cas où on a du contenu binaires par exemple un fichier multimédia codé en base 64, le parser altère t-il les données?

  10. #10
    Membre confirmé
    Inscrit en
    Mai 2007
    Messages
    335
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 335
    Points : 511
    Points
    511
    Par défaut
    Le Base64 ne contenant pas de caractères spéciaux, je ne pense pas que ça puisse poser de problème.

    Ceci dit, le CData est particulier à manipuler, si ça peut t'aider:
    http://access1.sun.com/techarticles/...TAArticle.html

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

Discussions similaires

  1. [PHP] Comment parser un XML sans racine ?
    Par Samax dans le forum Langage
    Réponses: 1
    Dernier message: 03/02/2011, 14h27
  2. [DOM] Parser un fichier xml (sans espaces et retours à la ligne)
    Par rizki1 dans le forum Format d'échange (XML, JSON...)
    Réponses: 7
    Dernier message: 04/05/2010, 11h26
  3. lecture d'un fichier sans le charger completement en mémoire
    Par Xx_raaY dans le forum Windows Forms
    Réponses: 3
    Dernier message: 19/03/2009, 19h55
  4. [SAX] Parser un XML sans DTD !
    Par ®om dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 18/04/2008, 13h09
  5. Parser un XML (sans ActiveX)
    Par nox75 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 29/08/2007, 14h40

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