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 :

Extraire informations avec un Filter [JDOM]


Sujet :

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

  1. #1
    Membre averti Avatar de mouss4rs
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    884
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 884
    Points : 355
    Points
    355
    Par défaut Extraire informations avec un Filter
    Bonjour,

    je debute sur SAX et JDom

    je narrive pqs a lire les infos dun fichier xml:

    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
     
     
    <?xml version="1.0" encoding="UTF-8"?>
    <personnes>
       <etudiant classe="P2">
          <nom>CynO</nom>
          <prenoms>
             <prenom>Nicolas</prenom>
             <prenom>Laurent</prenom>
          </prenoms>
       </etudiant>
       <etudiant classe="P1">
          <nom>Superwoman</nom>
       </etudiant>
       <etudiant classe="P1">
          <nom>Don Corleone</nom>
       </etudiant>
    </personnes>
    voici ma classe:

    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
     
    import java.io.*;
    import java.util.List;
    import java.util.Iterator;
     
    import org.jdom2.Document;
    import org.jdom2.Element;
    import org.jdom2.filter.Filter;
    import org.jdom2.input.SAXBuilder;
     
    public class JDom{
       static Document document;
       static Element racine;
     
       public static void main(String[] args){
          //On crée une instance de SAXBuilder
          SAXBuilder sxb = new SAXBuilder();
          try{
             //On crée un nouveau document JDOM avec en argument le fichier XML
             //Le parsing est terminé ;)
             document = sxb.build(new File("exemple 2.xml"));
          }catch(Exception e){}
     
          //On initialise un nouvel élément racine avec l'élément racine du document.
          racine = document.getRootElement();
     
          //Méthode définie dans la partie 3.2. de cet article
          //afficheALL();
          afficheFiltre();
       }
     //Ajouter cette méthodes à la classe JDOM2
       static void afficheALL(){
          //On crée une List contenant tous les noeuds "etudiant" de l'Element racine
          List listEtudiants = racine.getChildren("etudiant");
     
          //On crée un Iterator sur notre liste
          Iterator i = listEtudiants.iterator();
          while(i.hasNext()){
             //On recrée l'Element courant à chaque tour de boucle afin de
             //pouvoir utiliser les méthodes propres aux Element comme :
             //sélectionner un nœud fils, modifier du texte, etc...
             Element courant = (Element)i.next();
             //On affiche le nom de l’élément courant
             System.out.println(courant.getChild("prenom").getText());
          }
       }
     
     //Ajouter cette méthode à la classe JDOM2
     //Remplacer la ligne afficheALL(); par afficheFiltre();
     static void afficheFiltre(){
        //On crée un nouveau filtre
        Filter filtre = new Filter(){
           //On défini les propriétés du filtre à l'aide
           //de la méthode matches
           public boolean matches(Object ob){
              //1 ère vérification : on vérifie que les objets
              //qui seront filtrés sont bien des Elements
              if(!(ob instanceof Element)){return false;}
     
              //On crée alors un Element sur lequel on va faire les
              //vérifications suivantes.
              Element element = (Element)ob;
     
              //On crée deux variables qui vont nous permettre de vérifier
              //les conditions de nom et de prenom
              int verifNom = 0;
              int verifPrenom = 0;
     
              //2 ème vérification: on vérifie que le nom est bien "CynO"
              if(element.getChild("nom").getTextTrim().equals("CynO"))
              {
                 verifNom = 1;
              }
              //3 ème vérification: on vérifie que CynO possède un prenom "Laurent"
              //On commence par vérifier que la personne possède un prenom,
              //en effet notre fichier XML possède des étudiants sans prénom !
              Element prenoms = element.getChild("prenoms");
              if(prenoms == null){return false;}
     
              //On constitue une list avec tous les prenom
              List listprenom = prenoms.getChildren("prenom");
     
              //On effectue la vérification en parcourant notre liste de prenom
              //(voir: 3.1. Parcourir une arborescence)
              Iterator i = listprenom.iterator();
              while(i.hasNext())
              {
                 Element courant = (Element)i.next();
                 if(courant.getText().equals("Laurent"))
                 {
                    verifPrenom = 1;
                 }
              }
     
              //Si nos conditions sont remplies on retourne true, false sinon
              if(verifNom == 1 && verifPrenom == 1)
              {
                 return true;
              }
              return false;
           }
     
    	@Override
    	public Filter and(Filter arg0) {
    		// TODO Auto-generated method stub
    		return null;
    	}
     
    	@Override
    	public List filter(List arg0) {
    		// TODO Auto-generated method stub
    		return null;
    	}
     
    	@Override
    	public Object filter(Object arg0) {
    		// TODO Auto-generated method stub
    		return null;
    	}
     
    	@Override
    	public Filter negate() {
    		// TODO Auto-generated method stub
    		return null;
    	}
     
    	@Override
    	public Filter or(Filter arg0) {
    		// TODO Auto-generated method stub
    		return null;
    	}
     
    	@Override
    	public Filter refine(Filter arg0) {
    		// TODO Auto-generated method stub
    		return null;
    	}
        };//Fin du filtre
     
        //getContent va utiliser notre filtre pour créer une liste d'étudiants répondant
        //à nos critères.
        List resultat = racine.getContent(filtre);
        //On affiche enfin l'attribut classe de tous les éléments de notre list
        Iterator i = resultat.iterator();
        while(i.hasNext())
        {
           Element courant = (Element)i.next();
           System.out.println(courant.getAttributeValue("classe"));
        }
     }
     
    }

  2. #2
    Membre régulier Avatar de gloax29
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Finistère (Bretagne)

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 55
    Points : 70
    Points
    70
    Par défaut
    Bonsoir quel est le problème exact?

  3. #3
    Membre averti Avatar de mouss4rs
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    884
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 884
    Points : 355
    Points
    355
    Par défaut
    Je veux que mon programme me lise les enregistrement des balises
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    <prenom>Nicolas</prenom>
             <prenom>Laurent</prenom>

  4. #4
    Membre régulier Avatar de gloax29
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2002
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Finistère (Bretagne)

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

    Informations forums :
    Inscription : Juin 2002
    Messages : 55
    Points : 70
    Points
    70
    Par défaut
    Vu le code, la liste résultat est vide. Car aucune des méthodes n'est implémenté.
    Peut être qu en utilisant la méthode matches dans la méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    @Override
    	public Object filter(Object arg0) {
    		if(matches(arg0)){
     
    				return arg0 ;
     
    			}
    		return null;
    	}

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Element courant = (Element)i.next();
    	        System.out.println(courant.getAttributeValue("classe"));
    			for (Element el : courant.getChildren("prenoms")) {
    				for (Element el2 : el.getChildren()) {
     
    					System.out.println(el2.getText());
    				}
     
    			}

  5. #5
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Ça fait un moment que cette question me chiffonne, même si elle a été résolue, parce que c'est assez loin d'être idéal.

    Le problème ici était que l'interface Filter<E> de JDOM déclare autant de méthodes, ce qui force à les implémenter. Alors qu'en réalité on ne s'intéresse qu'à l'une d'entre elles : filter(Object content), qui renvoie null pour le contenu rejeté, et l'objet lui-même casté selon la généricité du Filter pour le contenu accepté.

    En principe pour implémenter seulement filter() et ne pas se taper toutes les autres, on utilise AbstractFilter, qui est là pour ça.
    Mais depuis Java 1.8 on se rend compte que cela a un gros défaut : Filter<E> ayant plusieurs méthodes abstraites, elle ne peut pas être une interface fonctionnelle, et on ne peut pas fournir une expression lambda là où un Filter est attendu. Ça aurait été plus pratique si Filter<E> avait déclaré seulement la méthode qui la justifie, et que tout le reste soit fourni par une classe utilitaire sur les filtres. En Java 1.8, toutes ces méthodes pourraient être des default methods de Filter<E>. Mais cela n'est possible que depuis Java 1.8 et en utilisant Java 1.8


    Et puis je me suis rendu compte que depuis Java 1.8, on a plus tellement besoin que JDOM fournisse son propre système de sélection avec filtres. On peut utiliser celui des streams.

    Le même code s'écrivant donc ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    racine.getChildren("etudiant").stream()
      .filter(e -> e.getChild("nom").getTextTrim().equals("CynO"))
      .filter(e -> {
        Element prenoms = e.getChild("prenoms");
        return prenoms != null && prenoms.getChildren("prenom").stream()
          .anyMatch(p -> p.getTextTrim().equals("Laurent"));
      })
      .forEach(e -> System.out.println(e.getAttributeValue("classe")));
    Je trouve ça nettement plus droit-au-but et satisfaisant que sous-classer AbstractFilter.

    (Petit bémol, ça marche avec getChildren() ou getContent() qui renvoient des List, mais pas avec getDescendants() qui renvoie un Iterable qui ne fournit pas directement de stream(). Dans ce cas-là on doit convertir en Stream soi-même avec StreamSupport.)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

Discussions similaires

  1. Plus d'information avec Spamassassin
    Par simoryl dans le forum Applications et environnements graphiques
    Réponses: 1
    Dernier message: 31/10/2006, 17h30
  2. probleme d'affichage des informations avec quickrep
    Par hamadi_insat dans le forum Bases de données
    Réponses: 1
    Dernier message: 14/09/2006, 19h31
  3. Extraire informations package rpm non installé
    Par adelavarenne dans le forum Linux
    Réponses: 3
    Dernier message: 13/09/2006, 16h47
  4. extraire chiffre avec regexp
    Par chillansky dans le forum ASP
    Réponses: 1
    Dernier message: 17/08/2006, 10h28
  5. Extraire informations d'une String
    Par Zapan dans le forum Langage
    Réponses: 8
    Dernier message: 07/01/2006, 20h28

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