diff options
Diffstat (limited to 'src/xml.c')
-rw-r--r-- | src/xml.c | 809 |
1 files changed, 0 insertions, 809 deletions
diff --git a/src/xml.c b/src/xml.c deleted file mode 100644 index 19003eb..0000000 --- a/src/xml.c +++ /dev/null @@ -1,809 +0,0 @@ - -/* Firebox Tools - Outils de configurations pour le WM Firebox - * xml.c - lecture ou écriture de documents XML - * - * Copyright (C) 2006-2007 Cyrille Bagard - * - * This file is part of Firebox Tools. - * - * Firebox Tools is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Firebox Tools is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "xml.h" - - -#include <stdarg.h> -#include <string.h> - - -#include "common/extstr.h" - - -#ifdef DEBUG -# define XML_LOG fprintf -#else -# define XML_LOG if (FALSE) fprintf -#endif - - - -/****************************************************************************** -* * -* 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 */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : filename = nom du fichier à ouvrir. * -* xdoc = structure XML chargée. [OUT] * -* xpathCtx = contexte à utiliser pour les recherches. [OUT] * -* * -* Description : Ouvre un fichier XML de façon encadrée. * -* * -* Retour : true si l'opération a pu s'effectuer, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -gboolean open_xml_file(const char *filename, xmlDoc **xdoc, xmlXPathContextPtr *xpathCtx) -{ - *xdoc = xmlParseFile(filename); - - if (*xdoc == NULL) - { - XML_LOG(stderr, "Can not parse the XML file '%s'\n", filename); - return FALSE; - } - - *xpathCtx = xmlXPathNewContext(*xdoc); - - if (*xpathCtx == NULL) - { - XML_LOG(stderr, "Unable to create new XPath context\n"); - xmlFreeDoc(*xdoc); - return FALSE; - } - - return TRUE; - -} - - -/****************************************************************************** -* * -* Paramètres : xpathCtx = contexte à utiliser pour les recherches. * -* path = chemin d'accès au noeud visé. * -* * -* Description : Obtient de façon encadrée l'accès à un noeud défini. * -* * -* Retour : Adresse de l'accès trouvé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -xmlXPathObjectPtr get_node_xpath_object(xmlXPathContextPtr xpathCtx, const char *path) -{ - xmlXPathObjectPtr result; /* Noeud XML à renvoyer */ - - result = xmlXPathEvalExpression(BAD_CAST path, xpathCtx); - - if (result == NULL) - { - XML_LOG(stderr, "Unable to evaluate xpath expression '%s'\n", path); - return NULL; - } - - if (result->nodesetval == NULL) - { - XML_LOG(stderr, "Node '%s' not found\n", path); - xmlXPathFreeObject(result); - return NULL; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud dont une propriété est à lire. * -* * -* Description : Obtient une valeur placée entre <...> et </...>. * -* * -* Retour : Valeur sous forme de chaîne de caractères ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *qck_get_node_text_value(xmlNodePtr node) -{ - char *result; /* Valeur en question renvoyée */ - - result = NULL; - - if (node != NULL) - if (node->children != NULL) - if (node->children->content != NULL) - result = strdup((char *)node->children->content); - - if (result == NULL) XML_LOG(stderr, "No text value for node '%s'\n", node->name); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : xpathCtx = contexte à utiliser pour les recherches. * -* path = chemin d'accès au noeud visé. * -* * -* Description : Obtient une valeur placée entre <...> et </...>. * -* * -* Retour : Valeur sous forme de chaîne de caractères ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *get_node_text_value(xmlXPathContextPtr xpathCtx, const char *path) -{ - char *result; /* Valeur en question renvoyée */ - xmlXPathObjectPtr xpathObj; /* Point de départ XML */ - - result = NULL; - - xpathObj = get_node_xpath_object(xpathCtx, path); - if (xpathObj == NULL) return NULL; - - if (xpathObj->nodesetval->nodeNr > 0) - result = qck_get_node_text_value(xpathObj->nodesetval->nodeTab[0]); - - xmlXPathFreeObject(xpathObj); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud dont une propriété est à lire. * -* name = nom de la propriété à lire. * -* * -* Description : Obtient la valeur d'une propriété d'un élément. * -* * -* Retour : Valeur sous forme de chaîne de caractères ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *qck_get_node_prop_value(xmlNodePtr node, const char *name) -{ - char *result; /* Valeur en question renvoyée */ - xmlAttrPtr attrib; /* Liste d'attributs présents */ - - result = NULL; - - if (node == NULL) return NULL; - - /* Lecture de la valeur */ - - for (attrib = node->properties; attrib != NULL && result == NULL; attrib = attrib->next) - if (xmlStrEqual(attrib->name, BAD_CAST name)) result = strdup((char *)attrib->children->content); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : xpathCtx = contexte à utiliser pour les recherches. * -* path = chemin d'accès au noeud à traiter. * -* name = nom de la propriété à lire. * -* * -* Description : Obtient la valeur d'une propriété d'un élément. * -* * -* Retour : Valeur sous forme de chaîne de caractères ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *get_node_prop_value(xmlXPathContextPtr xpathCtx, const char *path, const char *name) -{ - char *result; /* Valeur en question renvoyée */ - xmlXPathObjectPtr xpathObj; /* Point de départ XML */ - - result = NULL; - - xpathObj = get_node_xpath_object(xpathCtx, path); - if (xpathObj == NULL) return NULL; - - if (xpathObj->nodesetval->nodeNr > 0) - result = qck_get_node_prop_value(xpathObj->nodesetval->nodeTab[0], name); - - xmlXPathFreeObject(xpathObj); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : node = noeud de texte avec un lien avec le document XML. * -* * -* Description : Construit un chemin d'accès complet selon le fichier XML. * -* * -* Retour : Valeur à libérer de la mémoire après usage ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *qck_build_filename_with_doc_url(xmlNodePtr node) -{ - char *result; /* Construction à retourner */ - char *text; /* Valeur du texte lu */ - char *last; /* Point de remplacement */ - - result = NULL; - - text = qck_get_node_text_value(node); - - if (text != NULL) - { - result = (char *)calloc(xmlStrlen(node->doc->URL) + strlen(text) + 1, sizeof(char)); - - strcpy(result, (const char *)node->doc->URL); - - last = strrchr(result, '/'); - last++; - - strcpy(last, text); - free(text); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : xpathCtx = contexte à utiliser pour les recherches. * -* path = chemin d'accès au noeud à traiter. * -* * -* Description : Construit un chemin d'accès complet selon le fichier XML. * -* * -* Retour : Valeur sous forme de chaîne de caractères ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -char *build_filename_with_doc_url(xmlXPathContextPtr xpathCtx, const char *path) -{ - char *result; /* Valeur en question renvoyée */ - xmlXPathObjectPtr xpathObj; /* Point de départ XML */ - - result = NULL; - - xpathObj = get_node_xpath_object(xpathCtx, path); - if (xpathObj == NULL) return NULL; - - if (xpathObj->nodesetval->nodeNr > 0) - result = qck_build_filename_with_doc_url(xpathObj->nodesetval->nodeTab[0]); - - xmlXPathFreeObject(xpathObj); - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* OPERATIONS D'ECRITURE D'UN FICHIER XML */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : filename = nom du fichier à ouvrir. * -* * -* Description : Amorce l'écriture d'un nouveau fichier XML. * -* * -* Retour : Rédacteur mis en place ou NULL en cas d'erreur. * -* * -* Remarques : - * -* * -******************************************************************************/ - -xmlTextWriterPtr start_writing_xml_file(const char *filename) -{ - xmlTextWriterPtr result; /* Moyen à retourner */ - int retval; /* Bilan d'une opération */ - - result = xmlNewTextWriterFilename(filename, 0); - - if (result == NULL) - { - XML_LOG(stderr, "Error creating the xml writer\n"); - return NULL; - } - - retval = xmlTextWriterStartDocument(result, NULL, "UTF-8", "yes"); - if (retval < 0) - { - XML_LOG(stderr, "Error at xmlTextWriterStartDocument\n"); - xmlFreeTextWriter(result); - return NULL; - } - - retval = xmlTextWriterSetIndent(result, 1); - if (retval < 0) - { - XML_LOG(stderr, "Error setting indentation\n"); - xmlFreeTextWriter(result); - return NULL; - } - - retval = xmlTextWriterSetIndentString(result, BAD_CAST "\t"); - if (retval < 0) - { - XML_LOG(stderr, "Error setting indentation string\n"); - xmlFreeTextWriter(result); - return NULL; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : writer = rédacteur dédié à l'écriture. * -* * -* Description : Met fin à l'écriture d'un nouveau fichier XML. * -* * -* Retour : Bilan de l'opération : true ou false. * -* * -* Remarques : Ferme au besoin toutes les balises encore ouvertes. * -* * -******************************************************************************/ - -bool end_writing_xml_file(xmlTextWriterPtr writer) -{ - int retval; /* Bilan de l'opération */ - - retval = xmlTextWriterEndDocument(writer); - if (retval < 0) - { - XML_LOG(stderr, "Error at xmlTextWriterEndDocument\n"); - return false; - } - - xmlFreeTextWriter(writer); - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : writer = rédacteur dédié à l'écriture. * -* name = nom de la balise à écrire. * -* * -* Description : Ecrit une balise et ne la referme pas. * -* * -* Retour : Bilan de l'opération : true ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool open_xml_element(xmlTextWriterPtr writer, const char *name) -{ - int retval; /* Bilan de l'opération */ - - retval = xmlTextWriterStartElement(writer, BAD_CAST name); - - if (retval < 0) - XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); - - return (retval >= 0); - -} - - -/****************************************************************************** -* * -* Paramètres : writer = rédacteur dédié à l'écriture. * -* * -* Description : Ferme la dernière balise laissée ouverte. * -* * -* Retour : Bilan de l'opération : true ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool close_xml_element(xmlTextWriterPtr writer) -{ - int retval; /* Bilan de l'opération */ - - retval = xmlTextWriterEndElement(writer); - - if (retval < 0) - XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); - - return (retval >= 0); - -} - - -/****************************************************************************** -* * -* Paramètres : writer = rédacteur dédié à l'écriture. * -* name = nom de la balise à écrire. * -* format = format de la chaîne à traiter. * -* ... = informations à inscrire. * -* * -* Description : Ecrit une balise avec un contenu textuel. * -* * -* Retour : Bilan de l'opération : true ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool write_xml_element_with_content(xmlTextWriterPtr writer, const char *name, const char *format, ...) -{ - va_list ap; /* Liste d'arguments variable */ - int retval; /* Bilan de l'opération */ - - va_start(ap, format); - - retval = xmlTextWriterWriteVFormatElement(writer, BAD_CAST name, format, ap); - - if (retval < 0) - XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); - - va_end(ap); - - return (retval >= 0); - -} - - -/****************************************************************************** -* * -* Paramètres : writer = rédacteur dédié à l'écriture. * -* name = nom de l'attribut à écrire. * -* format = format de la chaîne à traiter. * -* ... = informations à inscrire. * -* * -* Description : Ecrit un attribut avec un contenu textuel. * -* * -* Retour : Bilan de l'opération : true ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool write_xml_attribute(xmlTextWriterPtr writer, const char *name, const char *format, ...) -{ - va_list ap; /* Liste d'arguments variable */ - int retval; /* Bilan de l'opération */ - - va_start(ap, format); - - retval = xmlTextWriterWriteVFormatAttribute(writer, BAD_CAST name, format, ap); - - if (retval < 0) - XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); - - va_end(ap); - - return (retval >= 0); - -} - - -/****************************************************************************** -* * -* Paramètres : writer = rédacteur dédié à l'écriture. * -* format = format de la chaîne à traiter. * -* ... = informations à inscrire. * -* * -* Description : Ecrit un contenu textuel. * -* * -* Retour : Bilan de l'opération : true ou false. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool write_xml_content(xmlTextWriterPtr writer, const char *format, ...) -{ - va_list ap; /* Liste d'arguments variable */ - int retval; /* Bilan de l'opération */ - - va_start(ap, format); - - retval = xmlTextWriterWriteVFormatString(writer, format, ap); - - if (retval < 0) - XML_LOG(stderr, "Error at xmlTextWriterWriteFormatElement\n"); - - va_end(ap); - - 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; - -} |