Exploration d'un document XML en langage C : Différence entre versions
imported>Jacques Ducloy (→Création d'un arbre à partir d'une chaîne) |
imported>Jacques Ducloy |
||
(6 révisions intermédiaires par le même utilisateur non affichées) | |||
Ligne 2 : | Ligne 2 : | ||
|module=Exploration d'un document XML en langage C | |module=Exploration d'un document XML en langage C | ||
|précédent=Introduction aux serveurs d'exploration sous Unix | |précédent=Introduction aux serveurs d'exploration sous Unix | ||
− | |suivant= | + | |suivant=Exploration d'un document de métadonnées en langage C |
}} | }} | ||
[[File:Dilib XmlProg C06-1.gif|400px|right|thumb|un arbre XML contenant 6 nœuds]] | [[File:Dilib XmlProg C06-1.gif|400px|right|thumb|un arbre XML contenant 6 nœuds]] | ||
Ligne 30 : | Ligne 30 : | ||
===Les voisins ou parents=== | ===Les voisins ou parents=== | ||
− | + | ||
− | Toutes les fonctions retournent un pointeur NULL en cas d'échec.</ | + | Toutes les fonctions retournent un pointeur NULL en cas d'échec. |
+ | |||
+ | Les 2 fonctions suivantes permettent d'accéder au premier et au dernier fils d'un noeud. | ||
+ | |||
+ | <source lang="c"> | ||
+ | SxmlNode *SxmlFirstChild(SxmlNode *node); | ||
+ | </source> | ||
+ | |||
<source lang="c"> | <source lang="c"> | ||
− | SxmlNode * | + | SxmlNode *SxmlLastChild(SxmlNode *node); |
</source> | </source> | ||
+ | Exemple : | ||
<source lang="c"> | <source lang="c"> | ||
− | + | ... | |
+ | SxmlPrint (SxmlFirstChild(myNodeTest)) ; /* imprime a1 */ | ||
+ | SxmlPrint (SxmlLastChild(myNodeTest)); /* imprime <c>c1</c> */ | ||
+ | ... | ||
</source> | </source> | ||
+ | |||
+ | |||
+ | Les 2 fonctions suivantes permettent d'accéder aux voisins (avant, après) d'un noeud. | ||
<source lang="c"> | <source lang="c"> | ||
− | SxmlNode * | + | SxmlNode *SgmlNextSibling(SxmlNode *node); |
</source> | </source> | ||
<source lang="c"> | <source lang="c"> | ||
− | SxmlNode * | + | SxmlNode *SxmlPreviousSibling(SxmlNode *node); |
</source> | </source> | ||
+ | |||
+ | Enfin cette fonction permet d'accéder au père. | ||
<source lang="c"> | <source lang="c"> | ||
Ligne 127 : | Ligne 143 : | ||
</source> | </source> | ||
− | ==Import | + | ==Import export de structures XML== |
− | + | La construction d'un arbre XML bien formé peut se faire sans DTD ni schéma. | |
===Conversion XML en string=== | ===Conversion XML en string=== | ||
Ligne 134 : | Ligne 150 : | ||
chaine (char *) de C. | chaine (char *) de C. | ||
− | + | Nous avons vu la construction d'un arbre XML à partir d'une chaîne. | |
<source lang="c"> | <source lang="c"> | ||
− | + | SxmlNode* SxmlFromString(char *string); | |
</source> | </source> | ||
− | + | Il est possible de convertir un arbre XML en String. | |
<source lang="c"> | <source lang="c"> | ||
− | + | char *SxmlToString (SgmlNode *node); | |
</source> | </source> | ||
Ligne 161 : | Ligne 177 : | ||
lecture du prochain document SGML sur l'entrée standard. | lecture du prochain document SGML sur l'entrée standard. | ||
<pre> | <pre> | ||
− | SgmlNode * | + | SgmlNode *SxmlInputGetDocumentElement(); |
</pre> | </pre> | ||
===Exemple=== | ===Exemple=== | ||
− | Impression de tous les premiers fils ayant «a» pour | + | Impression de tous les premiers fils ayant «a» pour balise. |
<source lang="c"> | <source lang="c"> | ||
Ligne 171 : | Ligne 187 : | ||
{ | { | ||
SxmlNode *docu ,*son; | SxmlNode *docu ,*son; | ||
− | while(docu= | + | while(docu=SxmlInputGetDocumentElement()) |
{ | { | ||
if (son=SxmlFirstChild(docu)) | if (son=SxmlFirstChild(docu)) | ||
Ligne 178 : | Ligne 194 : | ||
}}}; | }}}; | ||
} | } | ||
+ | </source> | ||
+ | |||
+ | Pour tester : | ||
+ | <source lang="xml"> | ||
+ | <doc>texte<a>ah ah</a><b><a>ne doit pas sortir</a></b><a><b>ici B dans A</b></a>fin</doc> | ||
</source> | </source> |
Version actuelle datée du 25 juin 2020 à 08:03
Exploration d'un document XML en langage C < = Introduction aux serveurs d'exploration sous Unix Exploration d'un document de métadonnées en langage C => |
Sommaire
Création d'un arbre à partir d'une chaîne
En langage C les chaînes de caractères sont de type char *
.
Dans la bibliothèque Dilib, il est très facile de construire un arbre XML à partir de la fonction SxmlFromString
.
SxmlNode *SxmlFromgString(char *string);
Exemple, pour créer l'arbre de la figure ci-dessus :
#include "SxmlNode.h"
#include <stdio.h>
main()
{
SxmlNode *myNodeTest;
...
myNodeTest=SxmlFromString("<a>a1<b>b1</b><c>c1</c></a>");
...
}
Accès à l'environnement d'un nœud
Les voisins ou parents
Toutes les fonctions retournent un pointeur NULL en cas d'échec.
Les 2 fonctions suivantes permettent d'accéder au premier et au dernier fils d'un noeud.
SxmlNode *SxmlFirstChild(SxmlNode *node);
SxmlNode *SxmlLastChild(SxmlNode *node);
Exemple :
...
SxmlPrint (SxmlFirstChild(myNodeTest)) ; /* imprime a1 */
SxmlPrint (SxmlLastChild(myNodeTest)); /* imprime <c>c1</c> */
...
Les 2 fonctions suivantes permettent d'accéder aux voisins (avant, après) d'un noeud.
SxmlNode *SgmlNextSibling(SxmlNode *node);
SxmlNode *SxmlPreviousSibling(SxmlNode *node);
Enfin cette fonction permet d'accéder au père.
SxmlNode *SgmlParent(SxmlNode *node);
Les caractéristiques d'un nœud
Pour un nœud de type SxmlElement
char *SxmlNodeName(node);
Pour un noeud de type SxmlText :
char *SxmlText(noeud);
test de type
int SgmlIsText(node);
int SgmlIsElement(node);
Itérations sur les composants d'un noeud
Principe
Toutes les fonctions renvoient la valeur NULL en cas d'échec ou d'absence d'un élément. Ceci permet de réaliser des itérations sur les objets XML contenus dans un élément.
Squelette d'une itérations sur les fils d'un nœud.
- Avec une boucle do
if ((fils = SxmlFirstChild (pere))) { do { traitement sur fils } while ((fils=SxmlNextSibling(fils))); } else { traitement de l'exception}
- Avec une boucle while
fils = SxmlFirstChild (pere); while (fils) { traitement sur fils fils=SxmlNextSibling(fils); }
Exemple
Édition de toutes les étiquettes des fils d'un nœud.
editChildTag ( SxmlNode *node)
{
SxmlNode *c1;
if ((c1=SxmlFirstChild(node)))
do{
if(SxmlIsElement(c1))
printf("%s\n",SgmlTag(c1));
} while ((son=SxmlNextSibling(c1)));
}
Itérateurs
Dans la bibliothèque Dilib, un itérateur est associé à un élément XML. La fonction SxmlNextNode
renvoie le fils suivant. La fonction SxmlReset
initialise l'itérateur. L'exemple précédent se réécrit ainsi.
editChildTag ( SxmlNode *node)
{
SxmlNode *c1;
SxmlReset (node);
while (c1=SxmlNextNode(node))
{
if(SxmlIsElement(c1)) printf("%s\n",SgmlTag(c1));
}
}
Import export de structures XML
La construction d'un arbre XML bien formé peut se faire sans DTD ni schéma.
Conversion XML en string
Les fonctions d'entreés sorties utilisent un noyau de 2 procédures de conversion vers les chaine (char *) de C.
Nous avons vu la construction d'un arbre XML à partir d'une chaîne.
SxmlNode* SxmlFromString(char *string);
Il est possible de convertir un arbre XML en String.
char *SxmlToString (SgmlNode *node);
Entrées-sorties
Les fonctions qui réalisent les entrées sorties sont réalisées à partir des fonction précédentes.
Impression d'un objet SGML sur la sortie standard :
SgmlPrint(node);
Impression d'un objet SGML dans un fichier :
SxmlFilePrint(FILE *file, SxmlNode* node); ;
lecture du prochain document SGML sur l'entrée standard.
SgmlNode *SxmlInputGetDocumentElement();
Exemple
Impression de tous les premiers fils ayant «a» pour balise.
#include "SxmlNode.h"
main()
{
SxmlNode *docu ,*son;
while(docu=SxmlInputGetDocumentElement())
{
if (son=SxmlFirstChild(docu))
{if (strcmp(SxmlNodeName(son), "a")==0)
{SxmlPrint(son);putchar('\n');
}}};
}
Pour tester :
<doc>texte<a>ah ah</a><b><a>ne doit pas sortir</a></b><a><b>ici B dans A</b></a>fin</doc>