Beispiel #1
0
/******************************************************************************
 **函数名称: 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;
}
Beispiel #2
0
/******************************************************************************
 **函数名称: _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;
}
Beispiel #3
0
/******************************************************************************
 **函数名称: 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;
}
Beispiel #4
0
/******************************************************************************
 **函数名称: 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;
}