Interfaces de programmation pour XML : SAX et DOM
API SAX
Principes
SAX permet un parcours générique d'un document XML, c'est-à-dire qu'il est indépendant du format.
SAX signifie Simple API for XML et est donc disponible dans différents langages de programmation, avec la même interface.
Le principe de SAX est simple : pour chaque ouverture ou fermeture d'élément, chaque feuille texte, etc. un événement (event) est déclenché. Le développeur doit simplement anticiper ces événements et leurs associer les instructions à effectuer lorsqu'ils se déclencheront.
SAX parcourt le document XML dans l'ordre du document et active du code associé selon les événements qui se déclenchent. De plus, contrairement à d'autres modèles de traitement XML (DOM, XPath et XSLT), SAX ne charge pas le document en mémoire mais se contente de le parcourir. SAX est donc particulièrement adapté pour réaliser des traitements XML simples, en séquence, éventuellement sur des fichiers XML très louds.
Écrire un parser SAX
Le programme principal débute par la création du parser et la fourniture du fichier à traiter.
Pour définir les actions effectuées par le parser, SAX permet de spécifier le comportement à avoir lorsque certains événements se déclenchent :
- startDocument: méthode appelée au début du document.
- endDocument: méthode appelée à la fin du document.
- startElement: méthode appelée à chaque fois qu'une balise ouvrante est rencontrée.
- endElement: méthode appelée à chaque fois qu'une balise fermante est rencontrée.
- characters: méthode appelée à chaque fois qu'une feuille textuelle est rencontrée.
API DOM
Introduction
DOM, pour Document Object Model, vise à fournir un modèle d'un document semi-structuré, autrement dit d'un document XML. Il s'agit en particulier de définir des méthodes d'accès et de modification opérant sur un tel document.
DOM est défini par des recommandations du W3C, trois niveaux ont aujourd'hui été définis. Certaines parties de ces recommandations sont dédiées au traitement de documents XHTML. L'API DOM est définie dans la majorité des langages de programmation mais l'utilisation majeure qui en est faite de nos jours réside dans le JavaScript des navigateurs web pour manipuler des documents html.
Le modèle DOM reflète la nature arborescente des documents XML : il nous permet d'accéder à la racine ou à des nœuds quelconques, d'obtenir les fils d'un nœud précis, ou encore ses frères. L'implémentation réelle du modèle présent en mémoire après le chargement du document XML est cachée dans un objet et peut varier avec le langage de programmation utilisé. Par contre les méthodes d'accès et de modification de l'arbre DOM sont standardisées par le W3C et sont donc les mêmes d'un langage à l'autre.
En pratique, DOM permet de charger un document XML tout entier en mémoire et s'oppose sur ce point à SAX (qui permet de traiter un document XML en une passe, sans occupation mémoire). Au minimum, DOM utilise une zone mémoire équivalente à la taille du fichier XML lu. Dans les faits, c'est souvent plus et cela pour se préparer à répondre de manière efficace à des interrogations complexes.
Précisons que chaque information présente dans le document d'origine se retrouve en mémoire comme un nœud de l'arbre DOM : les éléments, les attributs, les textes, les commentaires, etc. sont autant de nœuds accessibles dans l'arbre DOM.
Les nœuds du DOM
Nous venons de percevoir le rôle central des nœuds dans DOM, il convient de savoir les manipuler.
Informations sur un nœud
Étant donné un nœud de l'arbre DOM, nous pouvons obtenir son nom, sa valeur et son type.
nodeType | 1 (élément) | 2 (attribut) | 3 (texte) |
nodeName | le nom de la balise | le nom de l'attribut | #text |
nodeValue | non définie | la valeur de l'attribut | le texte du nœud |
Obtenir un nœud
À partir de l'objet DOM, il est possible d'obtenir :
- l'élément racine du document XML à l'aide de documentElement ;
- le nœud élément portant un nom particulier à l'aide de getElementsByTagName.
Si l'on possède déjà un nœud, il est alors possible d'en obtenir d'autres qui lui sont liés dans le document d'origine :
- childNodes : la liste des nœuds fils ;
- parentNode : le père ;
- firstChild : le premier fils ;
- lastChild : le dernier fils ;
- nextSibling : le frère droit ;
- previousSibling : le frère gauche.
À noter que le nœud demandé peut ne pas exister : la racine n'a pas de père, un fils ainé n'a pas de frère gauche, etc. Si un nœud n'a pas de fils, childNodes renvoie logiquement une liste vide.
Enfin les attributs d'un élément sont accessibles grâce à la méthode attributes (qui fournit donc un ensemble de nœuds de type 2).