/****************************************************************************** **函数名称: xml_mark_get_attr **功 能: 解析有属性的标签 **输入参数: ** ** stack: XML栈 ** parse: 解析文件缓存信息 **输出参数: **返 回: 0: 成功 !0: 失败 **实现描述: **注意事项: ** 1. 属性值可使用双引号或单引号确定属性值范围 ** 2. 转义符号的转换对应关系如下: ** < < 小于 ** > > 大于 ** & & 和号 ** ' ' 单引号 ** " " 引号 **作 者: # Qifeng.zou # 2013.02.18 # **修 改: # Qifeng.zou # 2014.01.06 # ******************************************************************************/ static int xml_mark_get_attr(xml_tree_t *xml, Stack_t *stack, xml_parse_t *parse) { char border = '"'; xml_node_t *node, *top; int len, errflg = 0; const char *ptr = parse->ptr; #if defined(__XML_ESC_PARSE__) int ret, size; xml_esc_split_t split; const xml_esc_t *esc = NULL; memset(&split, 0, sizeof(split)); #endif /*__XML_ESC_PARSE__*/ /* 1. 获取正在处理的标签 */ top = (xml_node_t*)stack_gettop(stack); if (NULL == top) { log_error(xml->log, "Get stack top failed!"); return XML_ERR_STACK; } /* 3. 将属性节点依次加入标签子节点链表 */ do { /* 3.1 新建节点,并初始化 */ node = xml_node_creat(xml, XML_NODE_ATTR); if (NULL == node) { log_error(xml->log, "Create xml node failed!"); return XML_ERR_CREAT_NODE; } /* 3.2 获取属性名 */ while (XmlIsIgnoreChar(*ptr)) { ++ptr; }/* 跳过属性名之前无意义的空格 */ parse->ptr = ptr; while (XmlIsMarkChar(*ptr)) { ++ptr; } /* 查找属性名的边界 */ len = ptr - parse->ptr; node->name.str = (char *)xml->alloc(xml->pool, (len+1)*sizeof(char)); if (NULL == node->name.str) { errflg = 1; log_error(xml->log, "Calloc failed!"); break; } memcpy(node->name.str, parse->ptr, len); node->name.len = len; node->name.str[len] = '\0'; /* 3.3 获取属性值 */ while (XmlIsIgnoreChar(*ptr)) { ++ptr; } /* 跳过=之前的无意义字符 */ if (!XmlIsEqualChar(*ptr)) { /* 不为等号,则格式错误 */ errflg = 1; log_error(xml->log, "Attribute format is incorrect![%-.32s]", parse->ptr); break; } ptr++; /* 跳过"=" */ while (XmlIsIgnoreChar(*ptr)) { ++ptr; }/* 跳过=之后的无意义字符 */ /* 判断是单引号(')还是双引号(")为属性的边界 */ if (XmlIsQuotChar(*ptr) || XmlIsSQuotChar(*ptr)) { border = *ptr; } else { /* 不为 双/单 引号,则格式错误 */ errflg = 1; log_error(xml->log, "XML format is wrong![%-.32s]", parse->ptr); break; } ptr++; parse->ptr = ptr; while ((*ptr != border) && !XmlIsStrEndChar(*ptr))/* 计算 双/单 引号之间的数据长度 */ { #if defined(__XML_ESC_PARSE__) if (XmlIsAndChar(*ptr)) { /* 判断并获取转义字串类型及相关信息 */ esc = xml_esc_get(ptr); /* 对包含有转义字串的字串进行切割 */ ret = xml_esc_split(xml, esc, parse->ptr, ptr-parse->ptr+1, &split); if (XML_OK != ret) { errflg = 1; log_error(xml->log, "Parse forwad string failed!"); break; } ptr += esc->len; parse->ptr = ptr; } else #endif /*__XML_ESC_PARSE__*/ { ptr++; } } if (*ptr != border) { errflg = 1; log_error(xml->log, "Mismatch border [%c]![%-.32s]", border, parse->ptr); break; } len = ptr - parse->ptr; ptr++; /* 跳过" */ #if defined(__XML_ESC_PARSE__) if (NULL != split.head) { size = xml_esc_size(&split); size += len+1; node->value = (char *)xml->alloc(xml->pool, size); if (NULL == node->value) { errflg = 1; log_error(xml->log, "Alloc memory failed!"); break; } xml_esc_merge(&split, node->value); strncat(node->value, parse->ptr, len); xml_esc_free(&split); } else #endif /*__XML_ESC_PARSE__*/ { node->value.str = (char *)xml->alloc(xml->pool, len+1); if (NULL == node->value.str) { errflg = 1; log_error(xml->log, "Calloc failed!"); break; } memcpy(node->value.str, parse->ptr, len); node->value.len = len; node->value.str[len] = '\0'; } /* 3.4 将节点加入属性链表 */ if (NULL == top->tail) { /* 还没有孩子节点 */ top->child = node; } else { top->tail->next = node; } node->parent = top; top->tail = node; /* 3.5 指针向后移动 */ while (XmlIsIgnoreChar(*ptr)) { ++ptr; } }while (XmlIsMarkChar(*ptr)); #if defined(__XML_ESC_PARSE__) xml_esc_free(&split); #endif /*__XML_ESC_PARSE__*/ if (1 == errflg) { /* 防止内存泄漏 */ xml_node_free(xml, node); node = NULL; return XML_ERR_GET_ATTR; } parse->ptr = ptr; xml_set_attr_flag(top); return XML_OK; }
/****************************************************************************** **函数名称: xml_add_attr **功 能: 往节点中添加属性节点 **输入参数: ** node: 需要添加属性节点的节点 ** attr: 属性节点(链表或单个节点) **输出参数: **返 回: 被创建节点的地址 **实现描述: 属性节点放在所有属性节点后面 **注意事项: 属性节点(attr)可以有兄弟节点 **作 者: # Qifeng.zou # 2013.03.01 # ******************************************************************************/ xml_node_t *xml_add_attr( xml_tree_t *xml, xml_node_t *node, const char *name, const char *value) { xml_node_t *attr, *parent = node->parent, *link = node->child; if (NULL == parent) { log_error(xml->log, "Please create root node at first!"); return NULL; } if (xml_is_attr(node)) { log_error(xml->log, "Can't add attr for attribute node!"); return NULL; } /* 1. 创建节点 */ attr = xml_node_creat_ext(xml, XML_NODE_ATTR, name, value); if (NULL == attr) { log_error(xml->log, "Create node failed!"); return NULL; } /* 2. 将节点放入XML树 */ if (NULL == link) { /* 没有孩子节点,也没有属性节点 */ node->child = attr; node->tail = attr; attr->parent = node; xml_set_attr_flag(node); return attr; } if (xml_has_attr(node)) { /* 有属性节点 */ if (xml_is_attr(node->tail)) { /* 所有子节点也为属性节点时,attr直接链入链表尾 */ attr->parent = node; node->tail->next = attr; node->tail = attr; xml_set_attr_flag(node); return attr; } while ((NULL != link->next) /* 查找最后一个属性节点 */ &&(xml_is_attr(link->next))) { link = link->next; } attr->parent = node; attr->next = link->next; link->next = attr; xml_set_attr_flag(node); return attr; } else if (xml_has_child(node) && !xml_has_attr(node)) { /* 有孩子但无属性 */ attr->parent = node; attr->next = node->child; node->child = attr; xml_set_attr_flag(node); return attr; } xml_node_free_one(xml, attr); log_error(xml->log, "Add attr node failed!"); return NULL; }