Partage
  • Partager sur Facebook
  • Partager sur Twitter

[XML][Récursivité] - Lire écrire un document XML

Hiérarchie des balises : test getChildNodes().getLength() pour getText

    19 juin 2019 à 11:09:50

    Bonjour,

    J'ai besoin de transformer un fichier XML, j'ai donc utilisé la méthode décrite ici (https://openclassrooms.com/fr/courses/2654406-java-et-le-xml/2686109-a-la-decouverte-de-dom), mais la récupération du texte est invalide quand on a plusieurs balises encapsulées n'ayant qu'un enfant :

    exemple : en entrée j'ai 

    	<AliTxInf>
    		<AliCmArea>
    			<AliReqdClrSys>YYYYY</AliReqdClrSys>
    		</AliCmArea>
    		<AliDtaToArch>1805XXXXX400078070                                XXXXX   XXXX002                                          1805XX</AliDtaToArch>
    	</AliTxInf>

             en sortie :

     		<AliTxInf>
     			<AliCmArea>YYYYY
     				<AliReqdClrSys>YYYYY</AliReqdClrSys>
          </AliCmArea>
     			<AliDtaToArch>098378258521714821                                TOXND   WDQA304                                          604272</AliDtaToArch>
    		</AliTxInf>

    la balise <AliCmArea> est valorisée à YYYYY (car elle n'a qu'un noeud enfant) alors qu'à l'origine elle ne l'est pas.

    Comment faire pour évaluer qu'on est au plus fin niveau de balise et ne faire le getTextContent que dans ce cas ?

    Ci-dessous le code utilisé :

    // Package ODPP
    package com.adt.FileMasking;
    //Java Input/Output global
    import java.io.*;
    import java.util.*;
    // package com.ibm.odppjavasample1;
    //import com.ibm.nex.odpp.Field;
    //import com.ibm.nex.odpp.FieldDescriptor;
    //import com.ibm.nex.odpp.NativeProvider;
    //import com.ibm.nex.odpp.ODPP;
    //import com.ibm.nex.odpp.ODPPRuntimeException;
    //import com.ibm.nex.odpp.ODPPException;
    //import com.ibm.nex.odpp.RowSet;
    //Parser
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    // XPath
    import javax.xml.xpath.XPath;
    import javax.xml.xpath.XPathConstants;
    import javax.xml.xpath.XPathExpressionException;
    import javax.xml.xpath.XPathFactory;
    //Sortie XML
    import javax.xml.transform.OutputKeys;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerConfigurationException;
    import javax.xml.transform.TransformerException;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    //API DOM
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.NamedNodeMap;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.xml.sax.ErrorHandler;
    import org.xml.sax.SAXException;
    import org.xml.sax.SAXParseException;
    import org.xml.sax.InputSource;
    
    public class XMLParser implements GlobalConstants {
    
        protected static void MaskXMLFile( String InFile, String OutFile) {
    
          DocumentBuilderFactory factoryS = DocumentBuilderFactory.newInstance();
          DocumentBuilderFactory factoryC = DocumentBuilderFactory.newInstance();
    
          try {
             //factoryS.setValidating(true);
             DocumentBuilder builderS = factoryS.newDocumentBuilder();
             // ErrorHandler errHandler = new SimpleErrorHandler();
             // builderS.setErrorHandler(errHandler);
             File fileXMLS = new File(InFile);
             Document xmlS;
             try {
                xmlS = builderS.parse(fileXMLS);
                Element rootS = xmlS.getDocumentElement();
             // APPEL A LA METHODE RECURSIVE
                String bodyS = description(rootS, "");
             //
    
             //   System.out.println("Root Name : " + rootS.getNodeName());
             //   System.out.println(bodyS);
    
                //Solution 1 : Writer
                //File file=new File(OutFile); // chemin absolu
                //file.createNewFile();
                //FileWriter writer=new FileWriter(file);
                //writer.write(bodyS); // ecrire une ligne dans le fichier resultat.txt
                //writer.close(); // fermer le fichier a la fin des traitements
    
                //Solution 2 : Builder / Transformer
                DocumentBuilder builderC = factoryC.newDocumentBuilder();
                StringReader readerC = new StringReader(bodyS);
                InputSource inputC = new InputSource(readerC); 
                Document xmlC = builderC.parse(inputC);
                TransformerFactory transformerFactory = TransformerFactory.newInstance();
                Transformer transformer = transformerFactory.newTransformer();
                DOMSource cible = new DOMSource(xmlC);
                File fileXMLC = new File(OutFile);
                StreamResult sortie = new StreamResult(fileXMLC);
                //  Prologue
                transformer.setOutputProperty(OutputKeys.VERSION, xmlS.getXmlVersion());
                transformer.setOutputProperty(OutputKeys.ENCODING, xmlS.getXmlEncoding());
                //transformer.setOutputProperty(OutputKeys.STANDALONE, xmlS.getXmlStandalone());
                //  Formatage
                transformer.setOutputProperty(OutputKeys.INDENT, "yes");
                transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
                // Sortie
                transformer.transform(cible, sortie);
                 
             } catch (TransformerConfigurationException e) {
    	  e.printStackTrace();
    	 }
    	   catch (TransformerException e) {
    	  e.printStackTrace();
    	 } catch (SAXParseException e) { }
          } catch (ParserConfigurationException e) {
             e.printStackTrace();
          } catch (SAXException e) {
             e.printStackTrace();
          } catch (IOException e) {
             e.printStackTrace();
          }
       }
       
       /**
        * Methode qui va parser le contenu d'un noeud
        * @param n
        * @param tab
        * @return
        */
       public static String description(Node n, String tab){
          String str = new String();
          //Test que le noeud passe en parametre est une instance d'Element
          // juste au cas ou il s'agisse d'un texte ou d'un espace, etc.
          if(n instanceof Element){
             
             //Cast l'objet de type Node en type Element
             Element element = (Element)n;
             
             //Recup du nom du noeud actuellement parcouru 
             //grace a cette mathode, on ouvre la balise
             str += "<" + n.getNodeName();
             
             //Controle de la liste des attributs presents
             if(n.getAttributes() != null && n.getAttributes().getLength() > 0){
                
                //Recuperation de la liste des attributs d'un element
                NamedNodeMap att = n.getAttributes();
                int nbAtt = att.getLength();
                
                //Parcours des noeuds pour affichage
                for(int j = 0; j < nbAtt; j++){
                   Node noeud = att.item(j);
                   //Recup du nom de l'attribut et de sa valeur avec ces deux methodes  
                   str += " " + noeud.getNodeName() + "=\"" + noeud.getNodeValue() + "\" ";
                }
             }
             
             //Fermeture de la balise
             str += ">";
             
             //La methode getChildNodes retournant le contenu du noeud + les noeuds enfants
             //Recup du contenu texte uniquement lorsqu'il n'y a que du texte, donc un seul enfant
    
             if(n.getChildNodes().getLength() == 1){
    //                 System.out.println(n.getNodeName());
    //                 System.out.println(n.getNodeValue());
                   if ( ruleMask.get(n.getNodeName()) != null  ) {
                     System.out.println("Noeud : " + n.getNodeName() +  " - Regle : " + ruleMask.get(n.getNodeName()));
                     System.out.println("Noeud : " + n.getNodeName() +  " - Valeur source  : " + n.getTextContent());
                     n.setTextContent(MaskOptim.maskOptim( ruleMask.get(n.getNodeName()), n.getTextContent()));
                     System.out.println("Noeud : " + n.getNodeName() +  " - Valeur masquee : " + n.getTextContent() + "\n");
                   }
    //
                  str += n.getTextContent();
             }
             //Traitement des noeuds enfants du noeud en cours de traitement
             int nbChild = n.getChildNodes().getLength();
             String niveau = Integer.toString(nbChild);
             //System.out.println("Noeud : " + n.getNodeName() +  " - Niveau : (" + niveau + ":" + sType + ") - Contenu : " + n.getTextContent() + " - Valeur : " + n.getNodeValue());
    
             //Recup de  la liste des noeuds enfants
             NodeList list = n.getChildNodes();
             String tab2 = tab + "\t";
             
             //Parcours de la liste des noeuds
             for(int i = 0; i < nbChild; i++){
                Node n2 = list.item(i);
                
                //si le noeud enfant est un Element, on le traite
                if (n2 instanceof Element){
                   // ! Appel recursif a la mathode pour le traitement du noeud et de ses enfants 
                   str += "\n " + tab2 + description(n2, tab2);
                } 
             }
             
             //Fermeture de la balise
             if(n.getChildNodes().getLength() < 2) {
                str += "</" + n.getNodeName() + ">";
             } else { 
                str += "\n" + tab +"</" + n.getNodeName() + ">";
             }
          }
          
          return str;
       }   
    }
    



    -
    Edité par PhilippeMongruel 19 juin 2019 à 11:46:40

    • Partager sur Facebook
    • Partager sur Twitter
      Staff 19 juin 2019 à 11:15:20

      Bonjour,

      Merci de colorer votre code à l'aide du bouton Code

      Les forums d'Openclassrooms disposent d'une fonctionnalité permettant de colorer et mettre en forme les codes source afin de les rendre plus lisibles et faciles à manipuler par les intervenants. Pour cela, il faut utiliser le bouton Code de l'éditeur, choisir un des langages proposés et coller votre code dans la zone prévue. Si vous utilisez l'éditeur de messages en mode Markdown, il faut utiliser les balises <pre class="brush: jscript;">Votre code ici</pre>.

      Mauvais titre

      Le titre est un élément important qui ne doit pas être négligé. N'oubliez pas cette règle simple : le titre idéal résume la question que vous allez poser en une petite phrase. Il doit permettre aux visiteurs de se repérer facilement dans le forum visité et d'identifier le sujet à sa seule lecture.

      Vous pouvez utiliser divers préfixes comme [Erreur], [MySQL], [Compatibilité], etc... Aussi, pensez à consulter les règles propres à chaque forum (visibles dans les topics épinglés en haut des sections).

      De plus, choisir un bon titre permet de rendre plus faciles les recherches des autres membres.

      Les titres de type "besoin d'aide" ou "problème" ne sont pas tolérés.

      Pour modifier votre titre, éditez le premier message de votre sujet.

      (titre originel : Parseur XML)

      • Partager sur Facebook
      • Partager sur Twitter
      Pas d'aide concernant le code par MP ni par mail, le forum est là pour ça :) Postez votre code html et css (bouton '</>') !!

      [XML][Récursivité] - Lire écrire un document XML

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      • Editeur
      • Markdown