FAQ Java XMLConsultez toutes les FAQ
Nombre d'auteurs : 5, nombre de questions : 59, dernière mise à jour : 3 septembre 2014 Ajouter une question
Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums de http://www.developpez.com et de l'expérience personnelle des auteurs.
Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant rédacteur, lisez ceci.
- Comment fonctionne l'API DOM ?
- Comment ouvrir un fichier XML avec DOM ?
- Comment gérer les erreurs durant la création d'un DOM ?
- Quelles informations peut-on récupérer sur un DOM ?
- Quels sont les différents types de nodes ?
- Comment parcourir l'arborescence d'un DOM ?
- Comment accèder au contenu et aux attributs d'un Element ?
- Comment connaitre le nombre d'enfants d'un Element ?
- Comment modifier un DOM (document, nodes et éléments) ?
- Comment créer un DOM de toute pièce ?
- Comment convertir un XML DOM en String ?
Pour commencer, l'application récupère un constructeur de documents (javax.xml.parsers.DocumentBuilder) à partir d'une fabrique de constructeurs (javax.xml.parsers.DocumentBuilderFactory).
C'est ce constructeur de documents qui va construire le DOM ou document (org.w3c.Document) à partir de la source XML.
Le Document est la représentation, sous forme d'arbre « d'objets », des données contenues dans le XML.
DOM reste une API de « bas niveau ». Si vous voulez travailler de manière plus orientée objet, avec des arbres XML, regardez du côté de jdom et dom4j (cf. Quelles autres API existent pour travailler avec XML ?).
Pour un exemple pratique d'utilisation, regardez : Comment ouvrir un fichier XML avec DOM ?
Voici un exemple, qui montre comment ouvrir un fichier XML avec l'API DOM :
Code Java : | Sélectionner tout |
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 | import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.*; import java.io.*; public class ExempleDOM{ public static void main(String[] args){ try{ // création d'une fabrique de documents DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance(); // création d'un constructeur de documents DocumentBuilder constructeur = fabrique.newDocumentBuilder(); // lecture du contenu d'un fichier XML avec DOM File xml = new File("ExempleDOM.xml"); Document document = constructeur.parse(xml); //traitement du document //voir ExempleDOM.zip }catch(ParserConfigurationException pce){ System.out.println("Erreur de configuration du parseur DOM"); System.out.println("lors de l'appel à fabrique.newDocumentBuilder();"); }catch(SAXException se){ System.out.println("Erreur lors du parsing du document"); System.out.println("lors de l'appel à construteur.parse(xml)"); }catch(IOException ioe){ System.out.println("Erreur d'entrée/sortie"); System.out.println("lors de l'appel à construteur.parse(xml)"); } } } |
Pour voir comment parcourir votre document, regardez : Comment parcourir l'arborescence d'un DOM ?
Vous pouvez télécharger un exemple simple (affichage sur la sortie standard du DOM) ci-dessous.
Tout comme pour SAX, on peut gérer les erreurs lors de la construction d'un Document grâce à un ErrorHandler.
Par exemple :
Code java : | Sélectionner tout |
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 | public class GestionnaireDErreurs implements ErrorHandler{ protected String message(SAXParseException e){ String message = "Message : "+e.getMessage()+"\n"; message += "Ligne "+e.getLineNumber()+", colonne "+e.getColumnNumber()+"\n"; message += "Public id : "+e.getPublicId()+"\n"; message += "System id : "+e.getSystemId(); return message; } protected void printSAXException(SAXParseException e){ System.out.println(message(e)); if(e.getException() != null){ e.getException().printStackTrace(); } } public void warning(SAXParseException exception) throws SAXException{ System.out.println("*** Warning ***"); printSAXException(exception); } public void error(SAXParseException exception) throws SAXException{ System.out.println("*** Erreur ***"); printSAXException(exception); } public void fatalError(SAXParseException exception) throws SAXException{ String message = "*** Erreur fatale ***\n"; message += message(exception); SAXException se = new SAXException(message, exception); throw se; } } |
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 | // création d'une fabrique de documents DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance(); // création et configuration du constructeur de documents DocumentBuilder constructeur = fabrique.newDocumentBuilder(); constructeurs.setErrorHandler(new GestionnaireDErreurs()); Document document = constructeur.parse(new File("ExempleDOM.xml")); |
Vous pouvez obtenir de nombreuses informations sur un document XML à partir d'une instance de org.w3c.dom.Document.
Voici un exemple récupérant, à partir d'un Document, des informations générales, des informations sur le type de document et sur la configuration DOM :
Code Java : | Sélectionner tout |
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 | public static void printDOMInfos(Document document){ System.out.println("INFORMATIONS GENERALES"); String uri = document.getDocumentURI(); System.out.println("URI = "+uri); String xVersion = document.getXmlVersion(); System.out.println("Version XML = "+xVersion); String xEncoding = document.getXmlEncoding(); System.out.println("XML encoding = "+xEncoding); String iEncoding = document.getInputEncoding(); System.out.println("Input encoding = "+iEncoding); boolean standalone = document.getXmlStandalone(); System.out.println("XML standalone = "+standalone); boolean strictError = document.getStrictErrorChecking(); System.out.println("Strict error checking = "+strictError+"\n"); System.out.println("DOCTYPE"); printDoctype(document.getDoctype()); System.out.println("CONFIGURATION"); printDOMConfiguration(document.getDomConfig()); } |
Pour le détail des méthodesprintDoctype et printDOMConfiguration, téléchargez le fichier ci-dessous.
Avant de commencer à parcourir un arbre DOM et à en extraire les données, il est nécessaire de bien comprendre sa structure. Il est notamment nécessaire de bien faire la distinction entre les différents types de nodes. Une erreur couramment commise est le fait de confondre Node et Element.
- Node (org.w3c.dom.Node) : un Node (ou nœud) est l'unité de base de l'arbre. Cela peut être du texte, un élément, une portion CDATA ou encore une instruction. Pour connaître le type d'un Node utilisez la méthode getNodeType().
- Element (org.w3c.dom.Element) : l'interface Element définit un élément au sens XML (XHTML ou HTML). Un élément est constitué d'un tag, d'attributs et d'un contenu (autres nodes et éléments).
Voici les différents types de nodes et le résultat des méthodes capables d'en découvrir le contenu.
Interface (org.w3c.dom) | getNodeType() (short) | getNodeName() (String) | getNodeValue() (String) | getAttributes() (NamedNodeMap) |
Attr | ATTRIBUTE_NODE | Le nom de l'attribut. | La valeur de l'attribut. | null |
CDATASection | CDATA_SECTION_NODE | "#cdata-section" | Le contenu de la section CDATA. | null |
Comment | COMMENT_NODE | "#comment" | Le contenu du commentaire. | null |
Document | DOCUMENT_NODE | "#document" | null | null |
DocumentFragment | DOCUMENT_FRAGMENT_NODE | "#document-fragment" | null | null |
DocumentType | DOCUMENT_TYPE_NODE | Le nom du type. | null | null |
Element | ELEMENT_NODE | Le nom du tag. | null | Les attributs de l'élément. |
Entity | ENTITY_NODE | Le nom de l'entité. | null | null |
EntityReference | ENTITY_REFERENCE_NODE | Le nom de l'entité réferencée. | null | null |
Notation | NOTATION_NODE | Le nom de la notation. | null | null |
ProcessingInstruction | PROCESSING_INSTRUCTION_NODE | La cible de l'instruction. | Les données de l'instruction. | null |
Text | TEXT_NODE | "#text" | Le texte en lui-même. | null |
Si vous voulez récupérer le texte contenu dans un node (et dans l'ensemble de ses enfants), utilisez la méthode getTextContent().
Pour éviter toute ambiguïté lors de l'utilisation d'Element, préférez les méthodes spécifiques de cette interface (cf. Comment accéder au contenu et aux attributs d'un Element ?).
La première chose à faire pour commencer à parcourir votre arbre DOM est de récupérer la racine.
Code java : | Sélectionner tout |
1 2 | Document document = ...; Element racine = document.getDocumentElement(); |
Méthodes de l'interface Node
- getChildNodes : retourne une NodeList contenant l'ensemble des nodes enfants ;
- getFirstChild : retourne le premier Node enfant ;
- getLastChild : retourne le dernier Node enfant ;
- getNextSibling : retourne la prochaine occurrence du Node ;
- getParentNode : retourne le nœud parent du Node ;
- getPreviousSibling: retourne la précédente occurrence du Node.
Méthodes de l'interface Element
- getElementsByTagName : retourne une NodeList contenant les éléments enfants dont le tag correspond au nom passé en paramètre (* pour renvoyer tous les éléments) ;
- getElementsByTagNameNS : même chose que getElementByTagName, avec prise en compte des namespace.
Pour accèder au contenu et aux attributs d'un Element, on peut utiliser les méthodes getTextContent et getAttributesByTagName.
Voici un exemple, dans lequel on extrait d'un XHTML les liens et leurs propriétés :
Code Java : | Sélectionner tout |
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 | public static List<Element> getLinks(String xhtmlUrl) throws Exception{ List<Element< liens = new ArrayList<Element>(); InputStream stream = null; try{ DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance(); fabrique.setValidating(true); DocumentBuilder constructeur = fabrique.newDocumentBuilder(); URL url = new URL(xhtmlUrl); stream = url.openStream(); Document document = constructeur.parse(stream); Element racine = document.getDocumentElement(); String tag = "a"; NodeList liste = racine.getElementsByTagName(tag); for(int i=0; i<liste.getLength(); i++){ Element e = (Element)liste.item(i); if(e.hasAttribute("href"))liens.add(e); } }catch(Exception e){ throw e; }finally{ try{stream.close();}catch(Exception e){} return liens; } } |
Code java : | Sélectionner tout |
1 2 3 4 5 6 7 8 | String url = "http://www.w3.org/"; List<Element> liens = getLinks(url); for(Element lien : liens){ String href = lien.getAttribute("href"); String texte = lien.getTextContent(); texte = (texte!=null)?texte:href; System.out.println("Lien "+texte+" pointe sur "+href); } |
Pour avoir plus d'informations sur un Element (ou un attribut) défini par un schéma, utilisez la méthode getSchemaTypeInfo().
Cela dépend de ce que vous entendez par « enfant ». Comme toujours, il faut bien faire la différence entre Node et Element.
Nombre d'enfants de type Node
Code java : | Sélectionner tout |
1 2 3 | Element e = ...; NodeList enfants = e.getChildNodes(); int nombreDeNoeudsEnfants = enfants.getLength(); |
Code java : | Sélectionner tout |
1 2 3 | Element e = ...; NodeList enfants = e.getElementsByTagName("*"); int nombreDElementsEnfants = enfants.getLength(); |
Ces méthodes sont relativement limitées. Pour des opérations plus complexes, regardez du côté de XPath : Qu'est-ce que XPath ? Pourquoi l'utiliser ?
L'API DOM fournit avec les classes Document, Node et ses dérivées (Element, par exemple) tout un ensemble de méthodes permettant la modification du document. Voici, en résumé, les méthodes disponibles pour Document, Node et Element.
Méthodes de Document
- adoptNode(Node source) : importe le nœud passé en paramètre. Si ce nœud appartient déjà à une arborescence, il en est supprimé. Le méthode retourne le nœud adopté ou null si l'opération échoue.
- importNode(Node importedNode, boolean deep) : importe, dans le document, le nœud passé en argument et ses enfants (si deep vaut true). Le nœud ainsi importé n'a pas de parent. Le nœud ainsi importé, contrairement à adoptNode, est une simple copie. Le nœud est retourné comme résultat.
- renameNode(Node n, String namespaceURI, String qualifiedName) : renomme le nœud passé en paramètre et retourne ce dernier. Attention, seuls les nodes de type item et Attr peuvent être ainsi renommés.
- setDocumentURI(String documentURI) : remplace l'URI du document.
- setXmlStandalone(boolean xmlStandalone) : définit si le XML est standalone ou non.
- setXmlVersion(String xmlVersion) : définit la version du XML ("1.0" par défaut).
- normalizeDocument() : cette méthode valide les modifications apportées au DOM. Voir aussi la méthode normalize() de l'interface Node.
Méthodes de Node
- appendChild(Node newChild) : ajoute le nœud passé en paramètre à la fin des autres enfants du node. cette méthode retourne le nœud ajouté.
- insertBefore(Node newChild, Node refChild) : insère newChild avant refChild et retourne newChild.
- removeChild(Node oldChild) : supprime le nœud passé en paramètre et le retourne.
- replaceChild(Node newChild, Node oldChild) : remplace oldChild par newChild et retourne oldChild.
- setNodeValue(String nodeValue) : met nodeValue comme valeur pour le nœud. Voir Quels sont les différents types de nodes ? pour connaître les valeurs possibles.
- setPrefix(String prefix) : met prefix comme nouveau préfixe du nœud.
- setTextContent(String textContent) : met textContent comme contenu du nœud. Attention, ceci supprime l'ensemble des nœuds enfants.
Méthodes de Element
- removeAttribute(String name) : supprime l'attribut nommé.
- setAttribute(String name, String value) : crée un nouvel attribut (ou modifie la valeur de l'attribut s'il existe déjà).
- setIdAttribute(String name, boolean isId) : crée un nouvel attribut de type ID (ou modifie la valeur de l'attribut s'il existe déjà).
Ces trois méthodes ont toutes des variantes. Les méthodes XXXNode permettent notamment de retourner l'instance de Attr modifiée ou supprimée.
Pour un exemple d'utilisation de quelques-unes de ces méthodes, regardez Comment créer un DOM de toutes pièces?
Ces méthodes ne modifient que l'arbre en mémoire. Pour modifier la source XML, vous devez utiliser XSLT : Comment créer ou modifier un fichier XML avec DOM et XSLT ?
La classe DocumentBuilder permet de créer une nouvelle instance de Document grâce à la méthode newDocument(). Pour le reste, Document fournit un ensemble de méthodes createXXX, qui vont vous permettre de créer des nodes, éléments, commentaires et attributs.
Voici un exemple :
Code Java : | Sélectionner tout |
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 | // Création d'un nouveau DOM DocumentBuilderFactory fabrique = DocumentBuilderFactory.newInstance(); DocumentBuilder constructeur = fabrique.newDocumentBuilder(); Document document = constructeur.newDocument(); // Propriétés du DOM document.setXmlVersion("1.0"); document.setXmlStandalone(true); // Création de l'arborescence du DOM Element racine = document.createElement("annuaire"); racine.appendChild(document.createComment("Commentaire sous la racine")); Element personne = document.createElement("personne"); personne.setAttribute("id","0"); racine.appendChild(personne); Element nom = document.createElement("nom"); nom.setTextContent("un nom"); personne.appendChild(nom); Element prenom = document.createElement("prenom"); prenom.setTextContent("un prénom"); personne.appendChild(prenom); Element adresse = document.createElement("adresse"); adresse.setTextContent("une adresse"); personne.appendChild(adresse); document.appendChild(racine); |
Code xml : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 | <?xml version="1.0" encoding="ISO-8859-1"?> <annuaire> <!--Commentaire sous la racine--> <personne id="0"> <nom>un nom</nom> <prenom>un prénom</prenom> <adresse>une adresse</adresse> </personne> </annuaire> |
Le bout de code suivant utilise la classe Transformer pour écrire un document DOM dans une String en passant par un StringWriter.
Code Java : | Sélectionner tout |
1 2 3 4 5 6 7 8 | Document document = ...; DOMSource domSource = new DOMSource(document); StringWriter writer = new StringWriter(); StreamResult result = new StreamResult(writer); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); transformer.transform(domSource, result); String stringResult = writer.toString(); |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.