Présentons à présent le fonctionnement de la partie DOM de l'API Xerces.
3.1. Organisation de l'API
L'API DOM de Xerces est divisée en deux parties. La partie standard DOM W3C se trouve dans la package
org.w3c.dom
, et l'implémentation dans le package
javax.xml.parsers
. Rappelons que Xerces est l'implémentation de référence du DOM W3C, et intégré au JDK. Il n'y a donc pas besoin d'ajouter de bibliothèques externes, comme dans le cas de DOM4J, puisque toutes les classes dont nous avons besoin se trouvent dans l'API standard de J2SE.
Notons aussi que, même si certaines classes ou interfaces de cette API portent le même nom que dans DOM4J, et représentent les mêmes notions, elles sont différentes et incompatibles.
Les types suivants sont définis :
-
Node
: super-interface de toutes les interfaces utilisées dans un document. On trouve 25 méthodes dans cette interface, qui permettent de manipuler le document, entre autres de gérer les nœuds, les attributs, les contenus, etc...
-
NodeList
: représente une collection ordonnée de nœuds. On peut regretter que cette interface n’ait pas de rapport avec l'API Collection.
-
Element
: représente un élément d’un document XML.
-
Attr
: interface qui code les attributs.
Les interfaces suivantes représentent les données équivalentes en XML.
-
CharacterData
: représente des données de type caractères de type
PCDATA
, prises en compte par l'analyseur XML.
-
Comment
: représente les données de type commentaires.
-
CDATASection
: représente des données de type caractères de type
CDATA
, non analysés.
-
Text
: représente les données textuelles.
-
Entity
: représente les données de type
ENTITY
.
-
EntityReference
: représente les données de type référence à des entités.
-
ProcessingInstruction
: représente des instructions de traitement.
Enfin, ces dernières interfaces représentent tout ou partie d’un document, ainsi que son type.
-
Document
;
-
DocumentFragment
;
-
DocumentType
.
L'interface de base de tous les objets que l'on manipule dans cette API est l'interface
Node
. Tous les objets du DOM étendent donc
Node
, même si certaines méthodes de
Node
n'ont pas de sens pour eux. Cette interface permet d'accéder au contenu d'un élément, à ses attributs, à son nom, etc... Elle gère aussi les relations parents / enfants.
Sans entrer dans le détail, citons ici :
-
Les méthodes qui permettent d’accéder aux noms du nœud, en fonction du mode dans lequel on se trouve :
getLocalName()
,
getNameSpaceURI()
,
getNodeName()
,
getPrefix()
.
-
Les méthodes qui gèrent les attributs :
getAttributes()
,
hasAttributes()
.
-
Les méthodes qui gèrent la valeur du nœud :
getNodeName()
,
getNodeType()
,
getNodeValue()
,
setNodeValue()
.
-
Les méthodes qui gèrent l’arborescence des nœuds :
-
Les méthodes pour ajouter, retirer ou remplacer des nœuds :
appendChild(Node)
,
removeChild(Node)
,
replaceChild(Node new, Node old)
,
insertBefore(Node new, Node ref)
.
-
Citons la méthode
cloneNode(Node)
, qui permet de dupliquer un nœud.
-
Enfin la méthode
getOwnerDocument()
renvoie une référence du
Document
qui contient ce nœud.
L'un des méthodes les plus importantes est la méthode
getNodeType()
, qui retourne le type du nœud que l'on est en train de manipuler. La bonne façon d'utiliser cette API est de vérifier ce type, puis d'appeler les méthodes qui ont un sens en fonction du nœud sur lequel on est. Effectivement, vue la façon dont les choses sont organisées, rien ne nous empêche de demander les enfants d'un nœud de type
Text
, ce qui n'a bien sûr pas de sens en XML.
À l'interface
Node
est ajoutée l'interface
NodeList
, qui permet de gérer une liste de
Node
. Cette interface n'a pas de rapport avec l'API Collection, elle ne gère notamment pas la notion d'itérateur, pourtant très utile.
Cette interface comporte deux méthodes :
-
getLength()
: renvoie le nombre de nœuds ;
-
item(int index)
: renvoie l’objet en position
index
dans la liste.
Cette interface code les éléments proprement dits. Elle étend
Node
. Elle comporte les méthodes suivantes :
-
getTagName()
: renvoie le nom de cet élément.
-
getElementsByTagName()
: renvoie un objet de type
NodeList
, qui contient tous les sous-éléments de cet élément.
-
hasAttribute()
: renvoie vrai si cet élément possède des attributs.
-
getAttribute()
,
getAttributeNode()
: permet d’obtenir un attribut à partir de son nom. La première méthode renvoie directement la valeur de cet attribut, sous forme de
String
, la seconde renvoie un objet de type
Attr
.
-
removeAttribute(String)
,
removeAttributeNode(Attr)
: retire un attribut spécifié par son nom ou par un objet de type
Attr
.
-
setAttribute(String, String)
,
setAttributeNode(Attr)
: ajoute un attribut spécifié par un nom et une valeur, ou par un objet de type
Attr
.
Cette interface code les attributs. Elle étend aussi l’interface
Node
. On y trouve les méthodes suivantes :
-
getName()
: permet d’obtenir le nom de cet attribut.
-
getValue()
,
setValue(String)
: gère la valeur de cet attribut.
-
getSpecified()
: permet de savoir si cet attribut a une valeur par défaut (
false
) ou pas.
-
getOwnerElement()
: renvoie une référence sur l’élément qui contient cet attribut.
3.6. Interface
CharacterData
Cette interface étend encore
Node
, et constitue la superinterface de trois autres :
CDATASection
,
Comment
et
Text
. Elle comporte 8 méthodes qui permettent de manipuler les données textuelles :
-
getData()
,
setData(String)
: permet d’obtenir ou de fixer les valeurs de données textuelles ;
-
getLength()
: renvoie la taille des données textuelles.
-
replaceData(int offset, int count, String)
: remplace un morceau de texte à l’endroit spécifié par
offset
et
count
.
-
substringData(int offset, int count)
: permet d’obtenir un fragment de données textuelles.
-
appendData(String)
: ajoute cette chaîne à la fin des données.
-
deleteData(int offset, int count)
: efface un fragment de données.
-
insertData(int offset, String)
: insère le fragment spécifié à l’endroit indiqué.
Cette interface étend
CharacterData
sans lui ajouter aucune méthode. Un commentaire est un fragment de texte non analysé, compris entre les caractères
<!--
et
-->
.
3.8. Interface
CDATASection
Cette interface étend également
CharacterData
et n’a aucune méthode. Une section de type
CDATA
se termine nécessairement par les caractères
]]>
.
Cette interface est aussi une extension de
CharacterData
. Elle ne supporte qu’une seule méthode, qui permet de faire deux nœuds frères d’un même texte :
splitText(int offset)
.
Cette interface étend
Node
, et ajoute trois méthodes :
-
getNotationName()
: pour les entités non analysées, le nom de
NOTATION
associé à cette entité.
-
getPublicId()
: l’identificateur
public
de cette entité.
-
getSystemId()
: l’identificateur
system
de cette entité.
3.11. Interface
EntityReference
Cette interface étend
Node
sans ajouter de méthode.
3.12. Interface
ProcessingInstruction
Cette interface étend
Node
en ajoutant trois méthodes :
-
getData()
: renvoie le contenu de ce nœud ;
-
getTarget()
: renvoie la cible de cette unité de traitement ;
-
setData(String)
: fixe la valeur du contenu de ce nœud.
Un objet de type
Document
représente l’intégralité d’un document XML. Les éléments et méthodes que l’on trouve dans cette interface constituent donc l’intégralité de ce que l’on peut faire avec.
L’interface
Document
contient toutes les méthodes qui permettent de créer un objet de type
Document
en mémoire, ou de lire un
Document
présent.
On trouve donc dedans des méthodes de création, qui commencent par
create
, suivi du nom de l’élément que l’on veut créer, comme
createAttribute(Attr)
.
Il y a deux méthodes de lecture :
-
getDocumentElement()
: qui renvoie un objet de type
Element
, qui contient le nœud racine du document.
-
getElementById(String)
: renvoie un objet de type
Element
dont l’identificateur est passé en paramètre.
-
getElementsByTagName(String)
: renvoie une liste de type
NodeList
de tous les éléments du document qui portent ce nom de tag. L’ordre dans lequel l’arbre du document est visité est spécifié.
On trouve aussi une méthode
getDocType()
, qui renvoie un objet de type *
DocumentType
, que nous allons voir plus loin.
Enfin, on trouve une méthode
importNode(Node, deep)
, qui permet d’importer un nœud complet. On pourra se reporter à la documentation pour connaître toutes les options d’importation qui existent.
3.14. Interface
DocumentFragment
Cette interface étend
Node
sans lui ajouter aucune méthode. Un objet de type
DocumentFragment
permet de créer des morceaux de documents, des sous-arbres qui pourront ensuite être assemblés en arbres complets.
3.15. Interface
DocumentType
L'attribut
DOCTYPE
d'un document est codé sous forme d’un objet de type
DocumentType
. Cette interface comporte six méthodes, parmi elles citons :
-
getName()
: renvoie le nom de la DTD.
-
getNotations()
,
getEntities()
: deux objets contenant les notations et les entités internes ou externes déclarées dans la DTD.