6. Sauvegarder ou afficher un arbre DOM via un document XML

Avant de passer à la modification d'un arbre DOM, il est nécessaire de savoir afficher ou sauvegarder l'arbre pour vérifier que l'on ne fait pas de bétises, et par la suite, parce qu'il faudra bien le transférer ailleurs, dans un fichier, à l'écran, ou sur le réseau!

Le plus simple pour afficher l'arbre DOM est d'utiliser xmlDocDump() qui prend en premier argument un flux de type FILE*, donc stdout pour la sortie écran, et en second argument, notre arbre de type xmlDocPtr. Mais on peut avoir une sortie formatée avec xmlDocFormatDump() qui prend les mêmes arguments, plus un troisième supplémentaire, de type int, qui est à 1 pour dire que l'on veut une sortie formatée, et à zéro sinon. Cela donne:

1 const char doc[] =
2   "<?xml version='1.0'?><racine><texte>blabla</texte><t2>ca</t2><t3>va</t3><t4><![CDATA[<bien?>]]></t4></racine>";
3 xmlDocPtr xmldoc = xmlParseMemory (doc, sizeof (doc));
4 xmlDocFormatDump (stdout, xmldoc, 1);

Et le résultat est:

<?xml version="1.0"?>
<racine>
  <texte>blabla</texte>
  <t2>ca</t2>
  <t3>va</t3>
  <t4>
<![CDATA[<bien?>]]>
  </t4>
</racine>

Bien évidemment, vous pouvez ouvrir un fichier avec fopen() et utiliser le flux vers le fichier ainsi ouvert avec xmlDocDump() qui a été aussi fait pour cela. Cependant, s'il s'agit de sauvegarder dans un fichier, on peut se passer de fopen() et fclose() en utilisant xmlSaveFile() ou xmlSaveFormatFile(). Ces deux fonctions prennent en premier argument un bon vieux const char* et en second argument le document XML de type xmlDocPtr, ce à quoi on pouvait s'attendre. Et xmlSaveFormatFile() prend un troisième argument, un entier, 1 pour une sortie formatée et 0 sinon, ce qui était aussi prévisible.

Il existe encore deux fonctions intéressantes, qui permettent de générer une chaîne de caractère en mémoire plutôt que d'en sortir son contenu vers un flux. Ces fonctions sont xmlDocDumpMemory() et xmlDocDumpFormatMemory(). Ces deux fonctions prennent en premier argument le document XML. Les arguements 2 et 3 sont un pointeur vers une chaîne de caractères et un pointeur vers un entier, car c'est ainsi que ces deux fonctions renvoient le résultat. Vous n'avez donc juste qu'à avoir initialisé un xmlChar* et un int dont vous allez fournir l'adresse. Enfin, xmlDocDumpFormatMemory() prend un quatrième argument, 1 pour une sortie formatée... Vous devez par contre ne pas oublier de libérer la mémoire que ces deux fonctions allouent pour la chaîne de caractères! Cela donne:

 1 xmlDocPtr xmldoc = NULL;
 2 const char doc[] =
 3   "<?xml version='1.0'?><racine><texte>blabla</texte><t2>ca</t2><t3>va</t3><t4><![CDATA[<bien?>]]></t4></racine>";
 4 xmlChar *str;
 5 int size;
 6 
 7 xmldoc = xmlParseMemory (doc, sizeof (doc));
 8 xmlDocDumpFormatMemory (xmldoc, &str, &size, 1);
 9 printf ("%s\n", str);
10 xmlFree (str);
11 xmlFreeDoc (xmldoc);
création est mise à disposition sous un contrat Creative Commons