#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"); snprintf(EMS_XML_item->ems_local_ip, NAME_STR_LEN, "%s", "192.168.0.111"); } //创建节点 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); xmlNewChild(EMS_XML_node, NULL, BAD_CAST"ems_local_ip", (xmlChar *)EMS_XML_item->ems_local_ip); 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); } if ((!xmlStrcmp(cur->name, (const xmlChar *)"ems_local_ip"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); int fd; char buffer[1024]; ssize_t bytes_read, bytes_written; fd = open("/etc/netplan/01-netcfg.yaml", O_RDWR); if (fd == -1) { perror("open the netcfg failed!"); return 1; } // 读取文件内容 bytes_read = read(fd, buffer, 1024); if (bytes_read == -1) { perror("read file failed!"); close(fd); return 1; } else if (bytes_read == 0) { printf("the file is empty\n"); close(fd); return 0; } buffer[bytes_read] = '\0'; // 定位包含 "addresses:" 的行 char *addresses_line = strstr(buffer, "addresses:"); if (addresses_line!= NULL) { // 定位冒号位置 char *colon_pos = strchr(addresses_line, ':'); if (colon_pos!= NULL) { colon_pos++; // 跳过可能的空格等字符,找到IP地址起始位置 while (*colon_pos!= '\0' && isspace(*colon_pos)) { colon_pos++; } // 记录IP地址起始位置 char *ip_start = colon_pos; // 找到IP地址结束位置(遇到逗号、换行符或右方括号且下一个字符不是数字) char *ip_end = ip_start; while (*ip_end!= '\0' && *ip_end!= ',' && *ip_end!= '\n' && ((*ip_end!= ']') || ((*ip_end == ']') && (!isdigit(*(ip_end + 1)))))) { ip_end++; } // 计算IP地址部分的长度 size_t ip_length = ip_end - ip_start; // 替换IP地址 memmove(colon_pos, key, strlen(key)); // 将剩余部分移动到新位置 memmove(colon_pos + strlen(key), ip_end, strlen(ip_end)); } } // 将文件指针移回文件开头 lseek(fd, 0, SEEK_SET); // 将修改后的内容写回文件 bytes_written = write(fd, buffer, strlen(buffer)); if (bytes_written == -1) { perror("write"); close(fd); return 1; } // 关闭文件 close(fd); printf("ems_local_ip: %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!, please modify the file directly!\n", EMS_XML_file); } else { //文件不存在,创建一个 create_EMS_XML_file(EMS_XML_file); } }