//=-------------------------------------------------------------------------=// // XML parsing module // // // // 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 . // //=-------------------------------------------------------------------------=// #include "../include/base.h" #include "../include/model.h" #include #include #include /* -------------------------------------------------------------------------- */ #define NO_DESTINATION NULL /* -------------------------------------------------------------------------- */ struct ModelParserTableXML_t; struct ParserTableXML_t { const xmlChar *tag; int (*parse) (xmlDoc*, struct ModelParserTableXML_t*, int currentParser, xmlNode*); void *destination; } typedef ParserTableXML_t; struct ModelParserTableXML_t { size_t len; ParserTableXML_t *table; } typedef ModelParserTableXML_t; /* -------------------------------------------------------------------------- */ int parseParentFieldXML(xmlDocPtr, ModelParserTableXML_t*, int, xmlNodePtr); int parseTextField(xmlDocPtr, ModelParserTableXML_t*, int, xmlNodePtr); /* -------------------------------------------------------------------------- */ // -------------------------------------------------------------------------- // // Parsing NOTHING // // -------------------------------------------------------------------------- // int parseStubFieldXML (xmlDocPtr doc, ModelParserTableXML_t *ModelTable, int currentParser, xmlNodePtr currentNode) { xmlChar *content; content = xmlNodeListGetString(doc, currentNode->xmlChildrenNode, 1); printLog("%s (stub): %s\n", ModelTable->table[currentParser].tag, content); xmlFree(content); return 0; } // -------------------------------------------------------------------------- // // Parsing a text field // // -------------------------------------------------------------------------- // int parseTextFieldXML (xmlDocPtr doc, ModelParserTableXML_t *ModelTable, int currentParser, xmlNodePtr currentNode) { xmlChar *content; content = xmlNodeListGetString(doc, currentNode->xmlChildrenNode, 1); printLog("%s: %s\n", ModelTable->table[currentParser].tag, content); strncpy((char *)ModelTable->table[currentParser].destination, (char *)content, MODEL_STRING_SIZE); xmlFree(content); return 0; } // -------------------------------------------------------------------------- // // Parsing a field that contains children fields // // -------------------------------------------------------------------------- // int parseParentFieldXML (xmlDocPtr doc, ModelParserTableXML_t *ModelTable, int currentParser, xmlNodePtr currentNode) { currentNode = currentNode->xmlChildrenNode; while (currentNode != NULL) { for (int i = 0; i < ModelTable->len; i++) { if ((!xmlStrcmp(currentNode->name, ModelTable->table[i].tag))) { ModelTable->table[i].parse(doc, ModelTable, i, currentNode); } } currentNode = currentNode->next; } return 0; } // -------------------------------------------------------------------------- // // Parsing a model file // // -------------------------------------------------------------------------- // int ParseModelXML(Model_t *model) { ParserTableXML_t table[] = { {(const xmlChar *)"identity", parseParentFieldXML, model}, {(const xmlChar *)"name", parseTextFieldXML, model->name}, {(const xmlChar *)"owner", parseTextFieldXML, model->owner}, {(const xmlChar *)"owner_id", parseStubFieldXML, model->owner_id}, {(const xmlChar *)"date", parseStubFieldXML, &model->date}, {(const xmlChar *)"version", parseTextFieldXML, model->version}, }; ModelParserTableXML_t modelParserTable = { LEN(table), &table[0] }; printLog("Parsing model %s\n", model->name); xmlDocPtr xmlDocument; xmlNodePtr currentNode; xmlDocument = xmlParseFile(model->filename); if (xmlDocument == NULL) { printLog("Can't parse model file at '%s'.\n", model->filename); return -1; } currentNode = xmlDocGetRootElement(xmlDocument); if (currentNode == NULL) { printLog("Invalid model file at '%s', document empty !\n", model->filename); xmlFreeDoc(xmlDocument); return -2; } if (xmlStrcmp(currentNode->name, (const xmlChar *) "gem-graph-model")) { printLog("Invalid model file at '%s', " "root node is not !\n", model->filename); xmlFreeDoc(xmlDocument); return -3; } currentNode = currentNode->xmlChildrenNode; while (currentNode != NULL) { for (int i = 0; i < modelParserTable.len; i++) { if ((!xmlStrcmp(currentNode->name, modelParserTable.table[i].tag))) { modelParserTable.table[i].parse(xmlDocument, &modelParserTable, i, currentNode); } } currentNode = currentNode->next; } xmlFreeDoc(xmlDocument); // Interpret what needs to be //model->date = strtol(date, NULL, 0); // validate when we're finished // model->validated = true; return 0; }