summaryrefslogtreecommitdiff
path: root/src/xml.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xml.c')
-rw-r--r--src/xml.c257
1 files changed, 246 insertions, 11 deletions
diff --git a/src/xml.c b/src/xml.c
index baa4eb2..19003eb 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -29,6 +29,9 @@
#include <string.h>
+#include "common/extstr.h"
+
+
#ifdef DEBUG
# define XML_LOG fprintf
#else
@@ -37,6 +40,88 @@
+/******************************************************************************
+* *
+* Paramètres : filename = nom du fichier à ouvrir. *
+* xdoc = structure XML chargée. [OUT] *
+* context = contexte à utiliser pour les recherches. [OUT] *
+* *
+* Description : Crée un nouveau fichier XML. *
+* *
+* Retour : true si l'opération a pu s'effectuer, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool create_new_xml_file(xmlDocPtr *xdoc, xmlXPathContextPtr *context)
+{
+ *xdoc = xmlNewDoc(BAD_CAST "1.0");
+
+ if (*xdoc == NULL)
+ return false;
+
+ *context = xmlXPathNewContext(*xdoc);
+
+ if (*context == NULL)
+ {
+ xmlFreeDoc(*xdoc);
+ return false;
+ }
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : xdoc = structure XML chargée. *
+* filename = nom du fichier à remplir. *
+* *
+* Description : Sauvegarde une structure XML dans un fichier. *
+* *
+* Retour : true si l'opération a pu s'effectuer, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool save_xml_file(xmlDocPtr xdoc, const char *filename)
+{
+ int ret; /* Bilan de l'appel */
+
+ ret = xmlSaveFormatFileEnc(filename, xdoc, "UTF-8", 1);
+
+ return (ret != -1);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : xdoc = structure XML chargée à supprimer. *
+* context = contexte utilisé pour les recherches. *
+* *
+* Description : Ferme une structure XML. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void close_xml_file(xmlDocPtr xdoc, xmlXPathContextPtr context)
+{
+ xmlXPathFreeContext(context);
+ xmlFreeDoc(xdoc);
+
+ xmlCleanupParser();
+
+}
+
+
+
/* ---------------------------------------------------------------------------------- */
/* OPERATIONS DE LECTURE D'UN FICHIER XML */
/* ---------------------------------------------------------------------------------- */
@@ -46,7 +131,6 @@
* *
* Paramètres : filename = nom du fichier à ouvrir. *
* xdoc = structure XML chargée. [OUT] *
-* xroot = noeud premier de l'ensemble des définitions.[OUT] *
* xpathCtx = contexte à utiliser pour les recherches. [OUT] *
* *
* Description : Ouvre un fichier XML de façon encadrée. *
@@ -57,7 +141,7 @@
* *
******************************************************************************/
-gboolean open_xml_file(const char *filename, xmlDoc **xdoc, xmlNode **xroot, xmlXPathContextPtr *xpathCtx)
+gboolean open_xml_file(const char *filename, xmlDoc **xdoc, xmlXPathContextPtr *xpathCtx)
{
*xdoc = xmlParseFile(filename);
@@ -67,15 +151,6 @@ gboolean open_xml_file(const char *filename, xmlDoc **xdoc, xmlNode **xroot, xml
return FALSE;
}
- *xroot = xmlDocGetRootElement(*xdoc);
-
- if (*xroot == NULL)
- {
- XML_LOG(stderr, "Can not access the root node in '%s'\n", filename);
- xmlFreeDoc(*xdoc);
- return FALSE;
- }
-
*xpathCtx = xmlXPathNewContext(*xdoc);
if (*xpathCtx == NULL)
@@ -572,3 +647,163 @@ bool write_xml_content(xmlTextWriterPtr writer, const char *format, ...)
return (retval >= 0);
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* OPERATIONS D'ECRITURE D'UN FICHIER XML */
+/* ---------------------------------------------------------------------------------- */
+
+
+
+/******************************************************************************
+* *
+* Paramètres : context = contexte à utiliser pour les recherches. *
+* path = chemin d'accès au noeud visé. *
+* *
+* Description : Fournit le premier noeud correspondant à un chemin XPath. *
+* *
+* Retour : Adresse du noeud trouvé ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+xmlNodePtr get_node_from_xpath(xmlXPathContextPtr context, const char *path)
+{
+ xmlNodePtr result; /* Noeud trouvé à renvoyer */
+ xmlXPathObjectPtr xobject; /* Point de départ XML */
+
+ result = NULL;
+
+ xobject = get_node_xpath_object(context, path);
+ if (xobject == NULL) return NULL;
+
+ if (xobject->nodesetval->nodeNr > 0)
+ result = xobject->nodesetval->nodeTab[0];
+
+ xmlXPathFreeObject(xobject);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : xdoc = structure XML chargée. *
+* context = contexte à utiliser pour les recherches. *
+* path = chemin d'accès au noeud visé. *
+* *
+* Description : S'assure qu'un noeud donné est bien présent dans le document.*
+* *
+* Retour : Noeud en question ou NULL en cas d'échec à la création. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+xmlNodePtr ensure_node_exist(xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path)
+{
+ xmlNodePtr result; /* Noeud à retourner */
+ char **levels; /* Niveaux dans le chemin */
+ size_t levels_count; /* Nombre de ces niveaux */
+ xmlNodePtr last; /* Dernier noeud valide */
+ size_t i; /* Boucle de parcours #1 */
+ char *iter_path; /* Chamin d'accès pour le test */
+ size_t j; /* Boucle de parcours #2 */
+ xmlNodePtr iter; /* Test d'accès à un noeud */
+ char *cond; /* Marque de condition ('[') */
+
+ result = get_node_from_xpath(context, path);
+
+ if (result == NULL)
+ {
+ levels = strtoka(path, "/", &levels_count);
+
+ /* Recherche la racine valide la plus haute */
+
+ last = xmlDocGetRootElement(xdoc);
+
+ for (i = 0; i < levels_count && last != NULL; i++)
+ {
+ iter_path = strdup("");
+
+ for (j = 0; j <= i; j++)
+ {
+ iter_path = stradd(iter_path, "/");
+ iter_path = stradd(iter_path, levels[j]);
+ }
+
+ iter = get_node_from_xpath(context, iter_path);
+
+ if (iter == NULL) break;
+ else last = iter;
+
+ }
+
+ /* Inscription des noeuds restants */
+
+ if (last == NULL)
+ {
+ last = xmlNewDocNode(xdoc, NULL, BAD_CAST levels[i++], NULL);
+ xmlDocSetRootElement(xdoc, last);
+
+ if (i == levels_count)
+ result = last;
+
+ }
+
+ for ( ; i < levels_count && last != NULL; i++)
+ {
+ cond = strchr(levels[i], '[');
+ if (cond != NULL) *cond = '\0';
+
+ result = xmlNewDocNode(xdoc, NULL, BAD_CAST levels[i], NULL);
+ result = xmlAddChild(last, result);
+ last = result;
+ }
+
+ /* Libération de la mémoire */
+
+ for (i = 0; i < levels_count; i++)
+ free(levels[i]);
+
+ free(levels);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : xdoc = structure XML chargée. *
+* context = contexte à utiliser pour les recherches. *
+* path = chemin d'accès au noeud visé. *
+* content = texte à inscrire en contenu. *
+* *
+* Description : S'assure qu'un noeud donné est bien présent dans le document.*
+* *
+* Retour : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool add_content_to_node(xmlDocPtr xdoc, xmlXPathContextPtr context, const char *path, const char *content)
+{
+ xmlNodePtr node; /* Noeud à modifier */
+
+ if (content == NULL) return true;
+
+ node = ensure_node_exist(xdoc, context, path);
+ if (node == NULL) return false;
+
+ xmlNodeSetContent(node, content);
+
+ return true;
+
+}