From 60624244e426a6b5c2e5e8cae49c1b5e2037f008 Mon Sep 17 00:00:00 2001 From: wangk <2865709459@qq.com> Date: Mon, 25 Nov 2024 16:14:09 +0800 Subject: [PATCH] Add XML create and parse function --- CMakeLists.txt | 4 +- kit/kit_xml.c | 272 +++++++++++++++++++++++++++++++++++++++++++++++++ kit/kit_xml.h | 32 ++++++ test/test.c | 18 +++- test/test.h | 1 + 5 files changed, 323 insertions(+), 4 deletions(-) create mode 100644 kit/kit_xml.c create mode 100644 kit/kit_xml.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e6662c..a8fb191 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,12 +63,14 @@ set(KIT_SOURCE ${PROJECT_SOURCE_DIR}/kit/kit_safe_memcpy.c ${PROJECT_SOURCE_DIR}/kit/kit_mqtt.c ${PROJECT_SOURCE_DIR}/kit/kit_mqtt_sub.c + ${PROJECT_SOURCE_DIR}/kit/kit_xml.c ) # 添加库头文件 include_directories( ${PROJECT_SOURCE_DIR}/lib/libsqlite3/include - ${PROJECT_SOURCE_DIR}/lib/libxml2/include + ${PROJECT_SOURCE_DIR}/lib/libxml2/include/ + ${PROJECT_SOURCE_DIR}/lib/libxml2/include/libxml2 ${PROJECT_SOURCE_DIR}/lib/libssl/include ${PROJECT_SOURCE_DIR}/lib/libcjson/include ${PROJECT_SOURCE_DIR}/lib/libmodbus/include diff --git a/kit/kit_xml.c b/kit/kit_xml.c new file mode 100644 index 0000000..845a24b --- /dev/null +++ b/kit/kit_xml.c @@ -0,0 +1,272 @@ +#include "kit_xml.h" + +//初始化结构体 +static void set_item(EMS_XML *EMS_XML_item) +{ + assert(EMS_XML_item); + + EMS_XML_item->id = 1; + snprintf(EMS_XML_item->can_recv_name, NAME_STR_LEN, "%s", "can0"); + snprintf(EMS_XML_item->can_send_name, NAME_STR_LEN, "%s", "can1"); + snprintf(EMS_XML_item->can_id_name, NAME_STR_LEN, "%s", "3"); + snprintf(EMS_XML_item->can_recv_dlc, NAME_STR_LEN, "%s", "8"); + snprintf(EMS_XML_item->can_send_dlc, NAME_STR_LEN, "%s", "8"); +} + +//创建节点 +static xmlNodePtr create_node(const EMS_XML *EMS_XML_item) +{ + //确保传入的指针不为空,避免后续对空指针进行不当操作 + assert(EMS_XML_item); + + char id[NAME_STR_LEN] = {0}; + xmlNodePtr EMS_XML_node = NULL; + + //BAD_CAST是一个将C风格字符串转成xmlChar*的宏 + EMS_XML_node = xmlNewNode(NULL, BAD_CAST"EMS_XML"); + if (EMS_XML_node == NULL) { + fprintf(stderr, "Failed to create new node.\n"); + return NULL; + } + //设置属性 + snprintf(id, NAME_STR_LEN, "%d", EMS_XML_item->id); + //xmlNewProp设置属性 + xmlNewProp(EMS_XML_node, BAD_CAST"id", (xmlChar*)id); + + xmlNewChild(EMS_XML_node, NULL, BAD_CAST"can_recv_name", (xmlChar *)EMS_XML_item->can_recv_name); + xmlNewChild(EMS_XML_node, NULL, BAD_CAST"can_send_name", (xmlChar *)EMS_XML_item->can_send_name); + xmlNewChild(EMS_XML_node, NULL, BAD_CAST"can_id_name", (xmlChar *)EMS_XML_item->can_id_name); + xmlNewChild(EMS_XML_node, NULL, BAD_CAST"can_recv_dlc", (xmlChar *)EMS_XML_item->can_recv_dlc); + xmlNewChild(EMS_XML_node, NULL, BAD_CAST"can_send_dlc", (xmlChar *)EMS_XML_item->can_send_dlc); + + return EMS_XML_node; +} + +//向根节点中添加一个节点 +static int add_node_to_root(xmlNodePtr root_node) +{ + xmlNodePtr EMS_XML_node = NULL; + EMS_XML *EMS_XML_item = NULL; + + //创建一个新的item + EMS_XML_item = (EMS_XML *)malloc(sizeof(EMS_XML)); + if (EMS_XML_item == NULL) { + fprintf(stderr, "Failed to malloc memory.\n"); + return -1; + } + set_item(EMS_XML_item); + + //创建一个节点 + EMS_XML_node = create_node(EMS_XML_item); + if (EMS_XML_node == NULL) { + fprintf(stderr, "Failed to create EMS_XML node.\n"); + goto FAILED; + } + //根节点添加一个子节点 + xmlAddChild(root_node, EMS_XML_node); + free(EMS_XML_item); + + return 0; +FAILED: + if (EMS_XML_item){ + free(EMS_XML_item); + } + return -1; +} + +//创建xml文档 +static int create_EMS_XML_file(const char *EMS_XML_file) +{ + assert(EMS_XML_file); + + xmlDocPtr doc = NULL; + xmlNodePtr root_node = NULL; + + //创建一个xml 文档 + doc = xmlNewDoc(BAD_CAST"1.0"); + if (doc == NULL) { + fprintf(stderr, "Failed to new doc.\n"); + return -1; + } + + //创建根节点 + root_node = xmlNewNode(NULL, BAD_CAST"EMS_root"); + if (root_node == NULL) { + fprintf(stderr, "Failed to new root node.\n"); + goto FAILED; + } + //将根节点添加到文档中 + xmlDocSetRootElement(doc, root_node); + + if (add_node_to_root(root_node) != 0) { + fprintf(stderr, "Failed to add a new EMS_XML node.\n"); + goto FAILED; + } + //将文档保存到文件中,按照utf-8编码格式保存 + xmlSaveFormatFileEnc(EMS_XML_file, doc, "UTF-8", 1); + //xmlSaveFile("test.xml", doc); + xmlFreeDoc(doc); + + return 0; +FAILED: + if (doc) { + xmlFreeDoc(doc); + } + + return -1; +} + +static int add_node(const char *EMS_XML_file) +{ + assert(EMS_XML_file); + + xmlDocPtr doc = NULL; + xmlNodePtr root_node = NULL; + xmlNodePtr EMS_XML_node = NULL; + EMS_XML *EMS_XML_item = NULL; + + doc = xmlParseFile(EMS_XML_file); + if (doc == NULL) { + fprintf(stderr, "Failed to parser xml file:%s\n", EMS_XML_file); + return -1; + } + + + root_node = xmlDocGetRootElement(doc); + if (root_node == NULL) { + fprintf(stderr, "Failed to get root node.\n"); + goto FAILED; + } + + //向根节点添加子节点 + if (add_node_to_root(root_node) != 0) { + fprintf(stderr, "Failed to add a new EMS_XML node.\n"); + goto FAILED; + } + //将文档保存到文件中,按照utf-8编码格式保存 + xmlSaveFormatFileEnc(EMS_XML_file, doc, "UTF-8", 1); + xmlFreeDoc(doc); + + return 0; +FAILED: + if (doc) { + xmlFreeDoc(doc); + } + + return -1; +} + +/*--------------------------para function--------------------------*/ +static int parse_EMS_XML_node(xmlDocPtr doc, xmlNodePtr cur) +{ + assert(doc || cur); + xmlChar *key; + + cur = cur->xmlChildrenNode; + while (cur != NULL) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"can_recv_name"))) { + key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + printf("can_recv_name: %s\t", key); + xmlFree(key); + } + + if ((!xmlStrcmp(cur->name, (const xmlChar *)"can_send_name"))) { + key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + printf("can_send_name: %s\t", key); + xmlFree(key); + } + + if ((!xmlStrcmp(cur->name, (const xmlChar *)"can_id_name"))) { + key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + printf("can_id_name: %s\n", key); + xmlFree(key); + } + + if ((!xmlStrcmp(cur->name, (const xmlChar *)"can_recv_dlc"))) { + key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + printf("can_recv_dlc: %s\t", key); + xmlFree(key); + } + + if ((!xmlStrcmp(cur->name, (const xmlChar *)"can_send_dlc"))) { + key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + printf("can_send_dlc: %s\n", key); + xmlFree(key); + } + cur = cur->next; + } + return 0; +} + +static int parse_EMS_XML(const char *file_name) +{ + assert(file_name); + + xmlDocPtr doc; //xml整个文档的树形结构 + xmlNodePtr cur; //xml节点 + xmlChar *id; + + //获取树形结构 + doc = xmlParseFile(file_name); + if (doc == NULL) { + fprintf(stderr, "Failed to parse xml file:%s\n", file_name); + goto FAILED; + } + + //获取根节点 + cur = xmlDocGetRootElement(doc); + if (cur == NULL) { + fprintf(stderr, "Root is empty.\n"); + goto FAILED; + } + + if ((xmlStrcmp(cur->name, (const xmlChar *)"EMS_root"))) { + fprintf(stderr, "The root is not EMS_root.\n"); + goto FAILED; + } + + //遍历处理根节点的每一个子节点 + cur = cur->xmlChildrenNode; + while (cur != NULL) { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"EMS_XML"))) { + id = xmlGetProp(cur, "id"); + printf("id:%s\t",id); + parse_EMS_XML_node(doc, cur); + } + cur = cur->next; + } + xmlFreeDoc(doc); + return 0; +FAILED: + if (doc) { + xmlFreeDoc(doc); + } + return -1; +} + +void paraXml() +{ + char *xml_file = DEFAULT_XML_FILE; + + printf("para xml function:\n"); + if (parse_EMS_XML(xml_file) != 0) { + fprintf(stderr, "Failed to parse EMS_XML_file.\n"); + exit(EXIT_FAILURE); + } + +} + + +void createXml() +{ + char *EMS_XML_file = EMS_XML_FILE; + + printf("create function:\n"); + if (access(EMS_XML_file, F_OK) == 0) { + printf("The %s is exist!\n", EMS_XML_file); + } + else { + //文件不存在,创建一个 + create_EMS_XML_file(EMS_XML_file); + } +} \ No newline at end of file diff --git a/kit/kit_xml.h b/kit/kit_xml.h new file mode 100644 index 0000000..257bcb4 --- /dev/null +++ b/kit/kit_xml.h @@ -0,0 +1,32 @@ +#ifndef __KIT_XML_H_ +#define __KIT_XML_H_ + + +#include +#include +#include +#include +#include +#include "libxml2/include/libxml2/libxml/parser.h" +#include "libxml2/include/libxml2/libxml/tree.h" +#include "libxml2/include/libxml2/libxml/xmlmemory.h" + +#define EMS_XML_FILE "EMS_XML.xml" +#define NAME_STR_LEN 32 +#define DEFAULT_XML_FILE "EMS_XML.xml" + + +//电话通讯录结构体 +typedef struct EMS_XML_t { + int id; //编号 + char can_recv_name[NAME_STR_LEN]; + char can_send_name[NAME_STR_LEN]; + char can_id_name[NAME_STR_LEN]; + char can_recv_dlc[NAME_STR_LEN]; + char can_send_dlc[NAME_STR_LEN]; +}EMS_XML; + +void createXml(); +void paraXml(); + +#endif \ No newline at end of file diff --git a/test/test.c b/test/test.c index 0d94e21..5a80b67 100644 --- a/test/test.c +++ b/test/test.c @@ -12,6 +12,7 @@ // #include "libmodbus/include/modbus-rtu.h" #include "kit_mqtt.h" #include "kit_mqtt_sub.h" +#include "kit_xml.h" // #include "MQTTAsync.h" @@ -29,7 +30,7 @@ void testCreatThreadTask() { printf("testThreadTask\n"); logger_init("./log"); - pthread_t tTestLogger, tTestDIDetect, tTestUart, tTestTcp, tTest4G, tTestCanSend, tTestCanRecv, tTestModbus, tTestMQTT; + pthread_t tTestLogger, tTestDIDetect, tTestUart, tTestTcp, tTest4G, tTestCanSend, tTestCanRecv, tTestModbus, tTestMQTT, tTestXML; // pthread_create(&tTestLogger, NULL, testLoggerThread, "testLoggerThread"); // pthread_join(tTestLogger, NULL); // int ret = pthread_create(&tTestDIDetect, NULL, testDIDetectThread, "testDIDetectThread"); @@ -47,8 +48,10 @@ void testCreatThreadTask() // pthread_join(tTestCanRecv, NULL); // pthread_create(&tTestModbus, NULL, testModbusThread, "testModbusThread"); // pthread_join(tTestModbus, NULL); - pthread_create(&tTestMQTT, NULL, testMQTTThread, "testMQTTThread"); - pthread_join(tTestMQTT, NULL); + // pthread_create(&tTestMQTT, NULL, testMQTTThread, "testMQTTThread"); + // pthread_join(tTestMQTT, NULL); + pthread_create(&tTestXML, NULL, testXMLThread, "testXMLThread"); + pthread_join(tTestXML, NULL); logger_destroy(); } @@ -204,3 +207,12 @@ void *testMQTTThread(void *arg) // printf("MQTT wrong\n"); // } } + +//XML测试线程 +void *testXMLThread(void *arg) +{ + logger_level_printf(LOGGER_DEBUG_LEVEL, arg); + printf("XML test!\n"); + createXml(); + paraXml(); +} diff --git a/test/test.h b/test/test.h index ee26a60..345aad3 100644 --- a/test/test.h +++ b/test/test.h @@ -15,5 +15,6 @@ void *testCanSendThread(void *arg); void *testCanRecvThread(void *arg); void *testModbusThread(void *arg); void *testMQTTThread(void *arg); +void *testXMLThread(void *arg); #endif