/****************************************************************************** **函数名称: xml_node_creat_ext **功 能: 创建XML节点 **输入参数: ** xml: XML树 ** type: 节点类型(xml_node_type_e) ** name: 节点名 ** vlaue: 节点值 **输出参数: NONE **返 回: 节点地址 **实现描述: **注意事项: **作 者: # Qifeng.zou # 2013.06.11 # ******************************************************************************/ xml_node_t *xml_node_creat_ext(xml_tree_t *xml, xml_node_type_e type, const char *name, const char *value) { int size; xml_node_t *node; /* 1. 创建节点 */ node = (xml_node_t*)xml->alloc(xml->pool, sizeof(xml_node_t)); if (NULL == node) { return NULL; } xml_node_init(node, type); /* 2. 设置节点名 */ size = strlen(name) + 1; node->name.str = (char *)xml->alloc(xml->pool, size); if (NULL == node->name.str) { xml_node_free_one(xml, node); return NULL; } node->name.len = snprintf(node->name.str, size, "%s", name); /* 3. 设置节点值 */ if (xml_set_value(xml, node, value)) { xml_node_free_one(xml, node); return NULL; } return node; }
/****************************************************************************** **函数名称: _xml_delete_empty **功 能: 删除无属性节、无孩子、无节点值的节点,同时返回下一个需要处理的节点(注: 不删属性节点) **输入参数: ** xml: XML树 **输出参数: NONE **返 回: 0:success !0:failed **实现描述: **注意事项: node节点必须为子节点,否则处理过程的判断条件会有错误!!! **作 者: # Qifeng.zou # 2013.10.21 # ******************************************************************************/ static xml_node_t *_xml_delete_empty(xml_tree_t *xml, Stack_t *stack, xml_node_t *node) { xml_node_t *parent, *prev; do { parent = node->parent; prev = parent->child; if (prev == node) { parent->child = node->next; xml_node_free_one(xml, node); /* 释放空节点 */ if (NULL != parent->child) { return parent->child; /* 处理子节点的兄弟节点 */ } /* 已无兄弟: 则处理父节点 */ xml_unset_child_flag(parent); /* 继续后续处理 */ } else { while (prev->next != node) { prev = prev->next; } prev->next = node->next; xml_node_free_one(xml, node); /* 释放空节点 */ if (NULL != prev->next) { return prev->next; /* 还有兄弟: 则处理后续节点 */ } else { /* 已无兄弟: 则处理父节点 */ if (xml_is_attr(prev)) { xml_unset_child_flag(parent); } /* 继续后续处理 */ } } /* 开始处理父节点 */ node = parent; stack_pop(stack); /* 删除无属性、无孩子、无节点值的节点 */ if (!xml_has_attr(node) && !xml_has_value(node) && !xml_has_child(node)) { continue; } if (NULL != node->next) { return node->next; /* 处理父节点的兄弟节点 */ } node = stack_pop(stack); } while(NULL != node); return NULL; }
/****************************************************************************** **函数名称: xml_free_next **功 能: 获取下一个需要被处理的节点 **输入参数: ** stack: 栈 ** curr: 当前正在处理的节点 **输出参数: **返 回: 下一个需要处理的节点 **实现描述: **注意事项: **作 者: # Qifeng.zou # 2013.02.27 # ******************************************************************************/ xml_node_t *xml_free_next(xml_tree_t *xml, Stack_t *stack, xml_node_t *curr) { xml_node_t *child, *top; /* 1. 释放孩子节点 */ if (NULL != curr->temp) { /* 首先: 处理孩子节点: 选出下一个孩子节点 */ child = curr->temp; curr->temp = child->next; curr = child; return curr; } else { /* 再次: 处理其兄弟节点: 选出下一个兄弟节点 */ /* 1. 弹出已经处理完成的节点, 并释放 */ top = stack_pop(stack); if (NULL == top) { log_error(xml->log, "Stack pop failed!"); return NULL; } if (stack_empty(stack)) { xml_node_free_one(xml, top); return NULL; } /* 2. 处理其下一个兄弟节点 */ curr = top->next; xml_node_free_one(xml, top); while (NULL == curr) /* 所有兄弟节点已经处理完成,说明父亲节点也处理完成 */ { /* 3. 父亲节点出栈 */ top = stack_pop(stack); if (NULL == top) { log_error(xml->log, "Stack pop failed!"); return NULL; } if (stack_empty(stack)) { xml_node_free_one(xml, top); return NULL; } /* 5. 选择父亲的兄弟节点 */ curr = top->next; xml_node_free_one(xml, top); } } return curr; }
/****************************************************************************** **函数名称: 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; }