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 :

Suppression de noeud [JDOM]


Sujet :

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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 84
    Par défaut Suppression de noeud
    Bonjour,
    Je sais comment supprimer des fils avec removeChildren, mais je n'arrive pas a supprimer l'element courant quand je parcours mon arborescence. Je précise que je suis novice en java.
    Voila à quoi ressemble mon 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
    - <BDD>
    - <UserId Id="62">
      <UserName>toto</UserName> 
      <email>toto@toto</email> 
      <language>FR</language> 
      <data>07/11/2011</data> 
      </UserId>
    - <UserId Id="53">
      <UserName>tata</UserName> 
      <email>tata@tata</email> 
      <language>US</language> 
      <data>2011/11/07</data> 
      </UserId>
      </BDD>
    Je parcours donc mon arborescence et je cherche à écrire une méthode qui supprimerait un noeud en fonction de son Id.
    Voilà ma méthode :

    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
    public void deleteXML(String Id)
    	{
    		List listUser = racine.getChildren();
    		Iterator i = listUser.iterator();
    		
    		while (i.hasNext())
    			{
    			Element courant = (Element)i.next();
    			if (courant.getAttributeValue("Id").equals(Id))
    			{
    				courant.detach();
    			}
    			}
    		try
    		   {
    		      XMLOutputter sortie = new XMLOutputter(Format.getPrettyFormat());
    		      sortie.output(document, new FileOutputStream("BDD.xml"));
    		   }
    		   catch (java.io.IOException e){}
    	}
    J'ai mis en rouge les points sur lesquels j'ai de gros doutes, .detach() parceque je ne l'ai jamais utilisé, et l'incrémentation parceque je ne sais pas si on peut continuer à parcourir une liste en ayant supprimé l'élément courant.
    Merci d'avance!
    Cordialement,
    Bdloul

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 84
    Par défaut
    Et puis vu que je cherche a delete des UserId en fonction de la valeur de leur attribut Id, je peux pas me servir de removeChild/removeChildren

  3. #3
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par Bdloul Voir le message
    Je sais comment supprimer des fils avec removeChildren, mais je n'arrive pas a supprimer l'element courant quand je parcours mon arborescence.
    C'est-à-dire ? Tu demandes sa suppression mais rien n'est supprimé ? Tu as un message d'erreur ? Parle de ton problème.


    Citation Envoyé par Bdloul Voir le message
    J'ai mis en rouge les points sur lesquels j'ai de gros doutes, .detach() parceque je ne l'ai jamais utilisé,
    detach() fonctionne parfaitement, et retire simplement un nœud du document qui le contenait. À noter que si on veut insérer un nœud dans un document, il ne doit pas déjà faire partie d'un document. D'où, je suppose, l'intérêt de detach(), qui enlève l'élément de là où il était, pour être sûr qu'il soit libre.

    Citation Envoyé par Bdloul Voir le message
    et l'incrémentation parceque je ne sais pas si on peut continuer à parcourir une liste en ayant supprimé l'élément courant.
    On peut mais, en effet, pas n'importe comment. Et pas comme ça.
    Il faut utiliser i.remove(), qui enlève le dernier élément obtenu par i.next(). Dans ce cas-là, on peut continuer à parcourir la liste ensuite.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 84
    Par défaut
    J'ai modifié le code =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    while (i.hasNext())
    			{
    			Element courant = (Element)i.next();
    			if (courant.getAttributeValue("Id").equals(Id))
    			{
    				courant.detach();
    			}
    			i.remove();
    			}
    Ca me semble plus sensé.
    L'erreur (même avec la modif) =>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Exception in thread "main" java.util.ConcurrentModificationException
    	at org.jdom.ContentList$FilterListIterator.checkConcurrentModification(ContentList.java:961)
    	at org.jdom.ContentList$FilterListIterator.nextIndex(ContentList.java:829)
    	at org.jdom.ContentList$FilterListIterator.remove(ContentList.java:921)
    	at ModeXML.deleteXML(ModeXML.java:61)
    	at FirstWindow.main(FirstWindow.java:10)
    La ligne 61 est en rouge

  5. #5
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    ?? detach() et remove() ??
    Quel intérêt d'enlever l'élément deux fois ??

    De toute façon, la seule manière d'enlever un élément d'une liste en train d'être parcourue, c'est i.remove(). Les autres provoquent un état instable et ont de bonnes chances de lancer un ConcurrentModificationException.

    Une fois l'élément enlevé avec i.remove(), tu peux appeler detach() tant que tu veux, mais en même temps ça sert plus à rien, puisqu'il a déjà été enlevé.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre Expert Avatar de tsuji
    Inscrit en
    Octobre 2011
    Messages
    1 558
    Détails du profil
    Informations forums :
    Inscription : Octobre 2011
    Messages : 1 558
    Par défaut
    En effet, il faut faire un peu plus d'attention à plusieurs points de détail. Je propose ce rendement qui fonctionne même en cas beaucoup plus général.
    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
    //...etc etc
    ElementFilter eFilter = new ElementFilter();
    Iterator i = racine.getDescendants(eFilter);
    List<Element> elemList = new ArrayList<Element>();
    while (i.hasNext()) {
        Element courant = (Element)i.next();
        //il faut assurer il y a d'attribut du tout
        if (!courant.getAttributes().isEmpty() && courant.getAttributeValue("Id").equals(Id)) {
            elemList.add(courant);
        }
    }
    for (Element elem : elemList) {
        elem.getParent().removeContent(elem);         
    }
    //etc etc...

  7. #7
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Ça marche, mais enfin, c'est quand même bigrement compliqué, alors que la méthode à base d'un itérateur sur lequel on appelle remove() se comprend tout de même assez bien.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 84
    Par défaut
    J'ai finalement utilisé la manière avec le remove, merci. En fait je faisais detach + .remove() en pensant que detach virerait l'élément de mon XML et remove de la list, sans penser qu'il n'y avait pas de différence dans ce cas là. Merci beaucoup.

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

Discussions similaires

  1. Duplication et suppression de noeud enfant en javascript
    Par kalbo dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 23/05/2008, 16h54
  2. [DOM XML] Suppression de noeud XML
    Par xenoox dans le forum Bibliothèques et frameworks
    Réponses: 7
    Dernier message: 02/05/2006, 03h37
  3. [DOM] - Suppression de noeud.
    Par jacquesh dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 17/02/2006, 11h34
  4. [DOM4J] Suppression de noeud
    Par tophebboy dans le forum Format d'échange (XML, JSON...)
    Réponses: 1
    Dernier message: 31/01/2006, 11h14
  5. Suppression de noeud en xml
    Par Qapoka dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 15/09/2005, 11h39

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