Introduction à la programmation en C des arbres Xml : Différence entre versions

De Wicri Manuel
imported>Jacques Ducloy
(Accès à l'environnement d'un nœud)
imported>Jacques Ducloy
(Principe)
Ligne 198 : Ligne 198 :
 
{{Wicri travaux|texte=cours en phase d'installation à partir de ce point}}
 
{{Wicri travaux|texte=cours en phase d'installation à partir de ce point}}
  
Squelette d'une itérations sur les fils d'un noeud</H2>
+
Squelette d'une itérations sur les fils d'un noeud.
  
<center><table border=4><tr><td>
+
<code>
<pre>
+
if ((son = SxmlFirstChild (node))
 
+
:{
if ((son = SgmlFirst (node))
+
::do  
    {
+
:::{ <i>traitement sur son</i> }
        do  
+
::::while ((son=SgmlNext(son));
          { <i>traitement sur son</i> }
+
:::}
while ((son=SgmlNext(son));
+
:}
    }
 
 
else
 
else
    { <i>traitement de l'exception </i>}
+
:{ <i>traitement de l'exception </i>}
<pre>
+
</code>
</td></tr></table></center>
 
  
<H2 CLASS="Intitul&eacute;2">
+
===Exemple===
 
+
Édition de toutes les étiquettes des fils d'un nœud.
Exemple</H2>
+
<source lang="c">
<P CLASS="Courant">
 
 
 
&eacute;dition de toutes les &eacute;tiquettes des fils d'un noeud</P>
 
<center><table border=4><tr><td>
 
<pre>
 
 
editSonTag(node)
 
editSonTag(node)
 
           SgmlNode *node;
 
           SgmlNode *node;
Ligne 233 : Ligne 226 :
 
</pre>
 
</pre>
 
</td></tr></table></center>
 
</td></tr></table></center>
 +
</source>
  
<address><a href=#sommaire>-&gt; sommaire</a></address>
+
==Import Export de structures SGML==
<a name=io>
 
<hr>
 
 
 
<H1 align=center>
 
Import Export de structures SGML</H1>
 
 
<P CLASS="Courant">
 
<P CLASS="Courant">
 
<A NAME="pgfId=141012">
 
<A NAME="pgfId=141012">

Version du 10 novembre 2013 à 20:12

Cette page reprend une section du cours qui était donné pour l'utilisation de la plateforme Dilib.

Arbres XML - notions de base

La bibliothèque Dilib est basée sur la norme XML avec des adaptations légères (Stream XML ou Sxml) pour pouvoir manipuler des grandes quantités de documents XML.

L'objet de base : SxmlNode

Les arbres Sxml sont réalisés à l'aide d'une structure élémentaire unique nommée "SxmlNode"

un arbre XML contenant 6 nœuds

Type de base : SxmlNode

Nous avons adopté "un style objet" en programmation C. Les arbres XML (ou les sous-arbres) seront toujours repérés pas des pointeurs sur des SxmlNode.

Les méthodes élémentaires associées aux objets SxmlNode

Tout objet de type SxmlNode aura trois méthodes permettant d'accéder au père et aux frères d'un nœud XML.

Accès au parent
SxmlNode *SxmlParent (SxmlNode *myNode);

Un nœud XML n'a, au plus, qu'un seul parent. C'est ainsi que des arbres peuvent être réalisés. Dans la figure précédente le noeud <b> est le parent de b1.

Accès au suivant
SxmlNode *SxmlNextSibling (SxmlNode *myNode);
Accès au précédant
SxmlNode *PreviousSibling (SxmlNode *myNode);

Types dérivés

A partir du type de base SxmlNode, un ensemble de types dérivés sont disponibles, nous nous intéressons maintenant aux 2 types permettant de réaliser l'essentiel des structures XML : les éléments XML (ici SxmlElement) qui réalisent le balisage et les zones de texte (SxmlText).

SxmlElement

Un objet de type SxmlElement est généralement la racine d'un sous-arbre. Dans la figure ci-dessus les nœuds <a>, <b> et <c> sont de type SxmlElement.

Accès au premier fils

La méthode permettant d'accéder au premier fils est :

   SxmlNode *SxmlFirstChild (SgmlNode *nx)

Les méthodes peuvent être combinées. Voici un exemple de programme que vous pouvez reproduire et adapter.

#include "SxmlNode.h"
#include <stdio.h>
main()
{
   SxmlNode *myNodeTest;  /* déclaration d'un pointeur qui sera associé 
                             à l'arbre donné en exemple */
   myNodeTest=SxmlFromString("<a>b1<c>c1</c></a>");
   SxmlPrint (myNodeTest);    /* doit imprimer : <a>b1<c>c1</c></a> */
   putchar ('\n');
   SxmlPrint (SxmlFirstChild(myNodeTest));    /* doit imprimer : b1 */
   putchar ('\n');
   SxmlPrint (SxmlNextSibling(SxmlFirstChild(myNodeTest)));    /* doit imprimer : <c>c1</c> */
   putchar ('\n');
}

Si ce programme est rangé dans le fichier myTest.c, dans le cas d'une installation locale standard, il pourra être compilé par :

. ~/Dilib/init.sh
gcc myTest.c $DILIB_CC -o myTest
./myTest
Accès au dernier fils
SxmlLastChild(SgmlNode *)

SxmlText

Un objet de type SxmlText contient une chaîne de caractères. Dans l'exemple ci-dessus, les parties « a1 », « b1 » et « c1 » sont de ce type.

Construction d'arbres Sxml

Constructeur de base

Toutes les fonctions de création utilisent un constructeur de base qui n'est pratiquement jamais directement utilisé par l'utilisateur. Ce paragraphe est donc simplement destiné à la compréhension de l'ensemble.

 SxmlNode *SxmlNodeCreate(type);
          char type;

Le type est un code interne qui définit le type de nœud. Par exemple le code XML_NODE_COMMENT (ou 8) est associé à un commentaire XML.[1]

Constructeurs effectivement utiles

Création d'un élément qui n'a pas encore de contenu.
SxmlNode *SxmlElementCreate(tag);
          char *tag;
Création d'un élément avec son contenu textuel. .
SgmlNode *SxmlLeafCreate(tag, string);
          char *tag;
          char *string;
Exemples
SxmlElementCreate("a");        /* construit <a></a> */

SxmlLeafCreat("a","text"); /* construit <a>text</a> */

Méthodes de construction de base

SxmlAddFirstChild et SxmlAppendChild

Ajout d'un nouvel élément en tête des fils
SxmlNode *SxmlAddFirstChild(pere, fils);
        SxmlNode *pere, *fils;
Ajout d'un nouvel élément en queue de la liste des fils
SxmlNode *SxmlAppendChild(SxmlNode *pere, SxmlNode * fils);

Exemple

/*  création de <a><b>b1</b><c>c1</c></a> */

#include "SxmlNode.h"
  main()
    {
        SxmlNode *root;
	root =SxmlElementCreate("a");
	SxmlAppendChild (root, SxmlLeafCreate("b", "b1"));
	SxmlAppendChild (root, SxmlLeafCreate("c", "c1"));
        SxmlPrint(root);
        putchar('\n');
        exit(0);
    }

Exercices

Modifier le programme précédent pour qu'il imprime le document XML donné en introduction de ce chapitre :  :

   <a>a1<b>b1</b><c>c1</c></a>

Écrire un programme qui produise le document suivant:

   <doc><tit>Tintin au Congo</tit><kw&gt<e>Tintin</e><e>Milou</e></kw></doc>

Accès à l'environnement d'un nœud

Les voisins ou parents

Toutes les fonctions retournent un pointeur NULL en cas d'échec.

SxmlNode *SgmlNextSibling(SxmlNode *node);
SxmlNode *SxmlPreviousSibling(SxmlNode *node);
SxmlNode *SxmlFirstChild(SxmlNode *node);
SxmlNode *SxmlLastChild(SxmlNode *node);
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.

logo travaux cours en phase d'installation à partir de ce point

Squelette d'une itérations sur les fils d'un noeud.

if ((son = SxmlFirstChild (node))

{
do
{ traitement sur son }
while ((son=SgmlNext(son));
}
}

else

{ traitement de l'exception }

Exemple

Édition de toutes les étiquettes des fils d'un nœud.

editSonTag(node)
          SgmlNode *node;
{
  SgmlNode *son;
  if ((son=SgmlFirst(node)))
	do{ if(SgmlIsMark(son))
	          printf(&quot;%s\n&quot;,SgmlTag(son));
      } while ((son=SgmlNext(son)));
}
</pre>
</td></tr></table></center>

Import Export de structures SGML

<A NAME="pgfId=141012"> </A> Si la chaîne d'entrée est en forme normale, la construction d'un arbre SGML peut se faire sans DTD.


Conversion SGML <-> string

Les fonctions d'entrées sorties utilisent un noyau de 2 procédures de conversion vers les chaine (char *) de C.

  • Conversion d'un arbre SGML en String
    char *SgmlToString(node);
          SgmlNode *node;
    <li>Construction d'un arbre SGML à partir d'une string.
    
    SgmlNode* SxmlFromString(string);
                       char *string;
    

Entrées-sorties (Dam = Dilib Access Method)

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, node);
                  FILE *file;
    
  • lecture du prochain document SGML sur l'entrée standard.
    SgmlNode *SxmlInputNextDocumentElement();
    

Exemple

Impression de tous les premiers fils ayant «a» pour tag.

#include «Sgml.h»
main()
{
  SgmlNode *docu ,*son;
  while(docu=SgmlInputNextDocument())
    {
       if (son=SgmlFirst(docu))
         {if (strcmp(SgmlTag(son),"a")==0)
                 {SgmlPrint(son);putchar('\n');
    }}};
}

<address><a href=#sommaire>-> sommaire</a></address>


   <a href="http://www.loria.fr/dilib"></a>
  [ <a href="http://www.loria.fr/projets/dilib/doc.html">Cours DILIB</a> ]

Voir aussi

notes
  1. La liste des codes peut être obtenue par la commande shell : grep "define XML_NODE" $DILIB/include/SxmlNode.h