Dom: instances de document xml

Une fois que vous avez décrit par un document xml un ensemble de donnée, un objet, un texte analysé ou toute autre chose, pour accéder à ce document à partir de Scriptol, une instance de dom doit être créée.
Dom signifie "Document Object Model", c'est un standard défini par le consortium web, (W3C). Cependant la classe dom qui est implémentée en scriptol va beaucoup loin que l'API (la librairie de fonction) définie par le W3C, tout en étant d'un emploi infiniment plus simple.


Pourquoi utiliser le dom?

 Scriptol permet d'utiliser des chemins vers un élément, comme cela sera décrit plus loin. Ces chemins sont associés à l'instance de dom plutôt qu'au nom du document.

Pourquoi accéder aux éléments du document xml à travers Dom et non pas directement?
Par exemple, si l'on a le document:
xml name = x
voiture
   passagers
   /passagers
/voiture
/xml
dom d = dom("x")

Pourquoi utiliser:     d.voiture.passagers
plutôt que :                x.voiture.passagers

En utilisant la classe dom nous pouvons:
- créer de multiple instances d'un même document xml, que nous pouvons adapter par la suite dans le contenu comme dans la structure.
- Dom dispose de fonctions que l'on peut appeler sur le document

Créer une instance

Syntaxe:

dom nominstance
nominstance.build()

ou

dom nominstance = dom("nomxml")

- nominstance est le nom de l'objet créé.
- nom xml est le nom d'un document xml préalablement défini dans un source Scriptol.

Pour utiliser la classe dom, il faut inclure le fichier externe: libdom.sol.
On utilise l'instruction include:

include "libdom.sol"

La création de l'instance crée une une arborescence vide. Il faut la faire suivre d'un appel à build() pour lui assigner le document xml défini dans le source ou inclus.
Il est aussi possible de la créer avec les instructions addChild() et addNext().


Notion de chemin

Soit le petit document xml suivant:

include "libdom.sol"

xml
  voiture
     conducteur nom = "Hill" /
     passager nom = "Epouse" /
     passager nom = "Fille" age="13" /
  /voiture
xml

dom ledom = dom()

print ledom.voiture.conducteur

Pour accéder à l'élément conducteur, le chemin est:

ledom.voiture.conducteur

C'est une écriture simplifiée. La fonction dom pour accéder à un élément xml est la fonction at("nom-élément").
at("nom-élément") peut être remplacé par nom-élément, donc:

ledom.at("voiture").at("conducteur") est équivalent à:
ledom.voiture.conducteur


Persistance

Quand un chemin est donné, le pointeur d'élément reste sur la position de l'élément pointé.
Si l'on veut pointer sur un élément sans exécuter aucune opération, il faut utiliser la méthode at() sans argument.

ledom.voiture.conducteur.at()

...est une instruction valide et est équivalente à:

ledom.voiture.at("conducteur")


Sélection d'un élément

Un élément xml peut être sélectionné selon le nom et la valeur d'un attribut.
Le chemin de l'élément contenant peut être donné, sinon on cherche à la position courante.

La syntaxe est la suivante:

nom-instance [chemin] [ nom-attribut : valeur-attribut ]

- nom de l'instance,
- chemin optionel,
- couple attribut et valeur entre crochets et séparés par un deux-points.

Exemple:

xml
  voiture
     conducteur nom = "Hill" /
     passager nom = "Epouse"
          "Lucida"
     /passager
     passager nom = "Fille" /
  /voiture
xml

dom ledom = dom()

print ledom.voiture.passager["nom" : "Epouse" ].getData()


Lire le contenu d'un élément

La fonction getData() retourne le contenu d'un élément, pointé ou dont le chemin est donné.

Dans l'exemple ci-dessus, l'instruction, qui comprend le chemin de l'élément, retourne "Lucida".

Si l'élément est déja pointé, on peut associer la méthode getData() au nom de l'instance, sans le chemin.

Exemple:

ledom.voiture.passager["nom" : "Epouse" ].at()
print
ledom.getData()

La première instruction pointe sur une élément, la seconde lit le contenu de cet élément.


Assigner le contenu à un élément

La fonction setData(texte) assigne ou change le contenu d'un élément pointé ou dont on spécifie le chemin.
Si nous voulons assigner "Christine" à l'élément, nous écrivons:

ledom.voiture.passager["nom" : "Epouse" ].setData("Christine")

Il est possible d'écrire directement:

ledom.voiture.passager["nom" : "Epouse" ] = "Christine"


Lire la valeur d'un attribut

L'accès à un attribut se fait comme ci-dessus avec le chemin de l'élément, mais avec la fonction getValue qui a pour argument le nom de l'attribut.

print ledom.voiture.passager["nom":"Fille"].getValue("age")
> 13

Le couple attribut : valeur désigne précisément l'élément, et l'on retourne la valeur de l'attribut "age".


Changer la valeur d'un attribut

On utilise la méthode setValue ayant pour arguments le nom et la valeur de l'attribut.
La valeur est changée si l'attribut existe, sinon une nouvel attribut est ajouté à l'élément.


Iterateur: parcours d'un document

L'itérateur est un ensemble de méthodes pour parcourir un document xml.
- On peut pointer sur un élément avec son chemin et la méthode at().
- La méthode reset() place le pointeur en tête du document.
- La méthode begin() remet le pointeur en tête du niveau.
- La méthode next() pointe l'index sur l'élément suivant au même niveau (à l'intérieur d'un élément contenant).
- up() revient au niveau du successeur de l'élément contenant l'élément courant.
- down() pointe sur le premier élément contenu dans l'élément courant.
- S'il n'y a plus d'élément, la méthode "found()" retourne faux (false).


Charger et sauver un document

Pour sauver le document, on utilise la méthode save avec l'instance de dom:
instance.save("nom de fichier" [, mode] )
Le mode par défaut est dom.XML, on peut utiliser aussi dom.LIGHT.

Charger un document, se fait avec un filtre capable de traiter tout document xml, la librairie libxml est utilisée pour cela et doit être liée au programme ainsi que le fichier lximport.lib, à travers le fichier de configuration (solc.ini ou nom-programme.cfg).
Cette librairie une fois accessible on peut utiliser la méthode load:
instance.load("nom de fichier")


Conclusion


Nous avons défini tout ce qui est nécessaire pour utiliser un document xml comme une classe, et comme une base de données simplifiée. Ce n'est qu'une infime partie des possibilité offertes par l'intégration de xml dans du code de programmation.

 Exercices

1) On a un mini dictionnaire français-anglais.
dict af = dict("oiseau" : "bird" , "voiture" : "car", "chien" : "dog")
Réécrivez le sous forme xml light, et afficher le document avec une méthode de dom.

Réponse

2) Nous allons appliquer un petit traitement sur un document xml, utilisable sur tout document xml contenant les mêmes éléments:

include "libxml.sol"

xml
  client  nom="A"
      "2356"
  /client
  client nom ="B"
      "-25"
  /client
/xml

Faire la somme des comptes clients avec une instance dom du document xml.
La variable "error" de dom vaut "vrai" quand un élément n'est pas trouvé.
(Vous ne pouvez pas interpréter le programme, il doit être compilé en exécutable).

Réponse