//=-------------------------------------------------------------------------=// // XML management tools // // // // Copyright © 2021 The Gem-graph Project // // // // This file is part of gem-graph. // // // // This program is free software: you can redistribute it and/or modify // // it under the terms of the GNU Affero General Public License as // // published by the Free Software Foundation, either version 3 of the // // License, or (at your option) any later version. // // // // This program 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 Affero General Public License for more details. // // // // You should have received a copy of the GNU Affero General Public License // // along with this program. If not, see . // //=-------------------------------------------------------------------------=// #ifndef BASE_H #include "../include/base.h" #endif /* -------------------------------------------------------------------------- */ #include #include #include #include /* -------------------------------------------------------------------------- */ static xmlDocPtr currentDocument = NULL; static xmlNodePtr currentDocumentRoot = NULL; /* -------------------------------------------------------------------------- */ // -------------------------------------------------------------------------- // // Open and set a document as current document // // -------------------------------------------------------------------------- // static inline void XmlSetNewDocument(const char *filename) { currentDocument = xmlParseFile(filename); if (currentDocument == NULL ) { printLog("%s not parsed successfully.\n", filename); xmlFreeDoc(currentDocument); currentDocument = NULL; return; } currentDocumentRoot = xmlDocGetRootElement(currentDocument); if (currentDocumentRoot == NULL ) { printLog("%s is invalid (no root)\n", filename); xmlFreeDoc(currentDocument); currentDocument = NULL; currentDocumentRoot = NULL; return; } } // -------------------------------------------------------------------------- // // Close and unset current document // // -------------------------------------------------------------------------- // static inline void XmlCloseCurrentDocument(void) { xmlFreeDoc(currentDocument); currentDocumentRoot = NULL; currentDocument = NULL; } // -------------------------------------------------------------------------- // // Reset current working root to document root // // -------------------------------------------------------------------------- // static inline void XmlResetWorkingRoot(void) { currentDocumentRoot = xmlDocGetRootElement(currentDocument); } // -------------------------------------------------------------------------- // // Parse content of a given XML tag // // -------------------------------------------------------------------------- // static inline int XmlParseTag(const char* tagName, char *destination, char destSize) { char *curString; size_t cursor = 0; char res = 0; xmlNodePtr cur = currentDocumentRoot; //printLog("Asked for %s\n", tagName); // Enumerate all brothers in tree from current root while (cur != NULL) { //printLog("\tGot %s (res = %d)\n", cur->name, res); // Check if current tag is the asked tag if ((!xmlStrcmp(cur->name, (const xmlChar *)tagName))) { //printLog("\tFound %s\n", cur->name); curString = (char*)xmlNodeListGetString(currentDocument, cur->xmlChildrenNode, 1); //printLog("\t\tString : %s\n", curString); // Check there is text in that tag (and that is asked) if (destination && curString[0] != '\n') { cursor = snprintf( destination + cursor * sizeof(char), destSize, "%s\n", curString); res++; } free(curString); } cur = cur->next; } return res; } // -------------------------------------------------------------------------- // // Find a working root for a given tag // // -------------------------------------------------------------------------- // static inline xmlNodePtr findWorkingRoot(const char *tagName, xmlNodePtr curRoot) { xmlNodePtr cur = curRoot; xmlNodePtr recur; //printLog("Asked for %s\n", tagName); while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)tagName))){ currentDocumentRoot = cur; return cur; } if (cur->xmlChildrenNode) { if ((recur = findWorkingRoot(tagName, (xmlNodePtr)cur->xmlChildrenNode)) != NULL) return recur; } cur = cur->next; } return NULL; } // -------------------------------------------------------------------------- // // Parse and validate an XML tree from given structural tree // // and current document // // -------------------------------------------------------------------------- // static inline int XmlParseTree(ModelField_t *curTree) { int currentOrSonCorrectlyParsed = 0; int curValueLen; while (curTree) { if (findWorkingRoot( curTree->tag, currentDocumentRoot->parent ) == NULL) { printLog("Error : can't find a new root\n"); return EBADF; } //printLog("Asked for %s\n", curTree->tag); // Try to parse current tag if (XmlParseTag(curTree->tag, curTree->destination, curTree->size) != 0) { // There are values in that tag if (curTree->destination[0]) if (!(curTree->destination[0] == '\0')) { curValueLen = strlen(curTree->destination); // Delete \n chars for(int i = 0; i < curValueLen; i++) { if(curTree->destination[i] == '\n') { memmove(&curTree->destination[i], &curTree->destination[i+1], curValueLen - i); curValueLen--; i--; } } printLog("Field %s: %s\n", curTree->tag, curTree->destination); } } else { // There aren't values in that tag if (curTree->mandatory) { // But it was mandatory printLog("Error : can't find %s\n", curTree->tag); return EBADF; } } if (curTree->son) currentOrSonCorrectlyParsed |= XmlParseTree(curTree->son); curTree = curTree->next; } return currentOrSonCorrectlyParsed; }