Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
/******************************************************************************
 **函数名称: xml_delete_empty
 **功    能: 删除无属性节、无孩子、无节点值的节点(注: 不删属性节点)
 **输入参数:
 **     xml: XML树
 **输出参数: NONE
 **返    回: 0:success !0:failed
 **实现描述: 
 **     1. 初始化栈
 **     2. 节点属性判断: 
 **注意事项: 
 **     1. 属性节点不用入栈
 **     2. 用于孩子节点的节点需要入栈
 **     3. 如为无属性节点、无孩子节点、且无节点值的节点,则删除之
 **作    者: # Qifeng.zou # 2013.10.21 #
 ******************************************************************************/
int xml_delete_empty(xml_tree_t *xml)
{
    xml_node_t *node;
    Stack_t _stack, *stack = &_stack;

    if (stack_init(stack, XML_MAX_DEPTH)) {
        log_error(xml->log, "Init stack failed!");
        return XML_ERR_STACK;
    }

    node = xml->root->child;
    while (NULL != node) {
        /* 1. 此节点为属性节点: 不用入栈, 继续查找其兄弟节点 */
        if (xml_is_attr(node)) {
            if (NULL != node->next) {
                node = node->next;
                continue;
            }

            /* 属性节点后续无孩子节点: 说明其父节点无孩子节点, 此类父节点不应该入栈 */
            log_error(xml->log, "Push is not right!");
            return XML_ERR_STACK;
        }
        /* 2. 此节点有孩子节点: 入栈, 并处理其孩子节点 */
        else if (xml_has_child(node)) {
            if (stack_push(stack, node)) {
                log_error(xml->log, "Push failed!");
                return XML_ERR_STACK;
            }
            
            node = node->child;
            continue;
        }
        /* 3. 此节点为拥有节点值或属性节点, 而无孩子节点: 此节点不入栈, 并继续查找其兄弟节点 */
        else if (xml_has_value(node) || xml_has_attr(node)) {
            do {
                /* 3.1 查找兄弟节点: 处理自己的兄弟节点 */
                if (NULL != node->next) {
                    node = node->next;
                    break;
                }

                /* 3.2 已无兄弟节点: 则处理父节点的兄弟节点 */
                node = stack_pop(stack);
            } while(1);
            continue;
        }
        /* 4. 删除无属性、无孩子、无节点值的节点 */
        else { /* if (!xml_has_attr(node) && !xml_has_child(node) && !xml_has_value(node) && !xml_is_attr(node)) */
            node = _xml_delete_empty(xml, stack, node);
        }
    }

    stack_destroy(stack);
    
    return XML_OK;
}
Ejemplo n.º 3
0
/******************************************************************************
 **函数名称: xml_node_next_len
 **功    能: 获取下一个要处理的节点,并计算当前结束节点的长度(注: XML有层次结构)
 **输入参数:
 **     root: XML树根节点
 **     stack: 栈
 **输出参数:
 **返    回: 0:成功 !0:失败
 **实现描述: 
 **注意事项: 
 **作    者: # Qifeng.zou # 2013.06.10 #
 ******************************************************************************/
static xml_node_t *xml_node_next_len(
    xml_tree_t *xml, Stack_t *stack, xml_node_t *node, int *len)
{
    xml_node_t *top, *child;
    int depth, level, len2;

    /* 首先: 处理孩子节点: 选出下一个孩子节点 */
    if (NULL != node->temp) {
        child = node->temp;
        node->temp = child->next;
        node = child;
        return node;
    }

    /* 再次: 处理其兄弟节点: 选出下一个兄弟节点 */

    len2 = 0;

    /* 1. 弹出已经处理完成的节点 */
    top = stack_gettop(stack);
    if (xml_has_child(top)) {
        depth = stack_depth(stack);
        level = depth - 1;
        while (level > 1)
        {
            /* fprintf(fp, "\t"); */
            len2++;
            level--;
        }
        /* fprintf(fp, "</%s>\n", top->name); */
        len2 += (top->name.len + 4);
    }

    if (NULL == stack_pop(stack)) {
        *len += len2;
        log_error(xml->log, "Stack pop failed!");
        return NULL;
    }

    if (stack_empty(stack)) {
        *len += len2;
        log_error(xml->log, "Compelte fprint!");
        return NULL;
    }

    /* 2. 处理其下一个兄弟节点 */
    node = top->next;
    while (NULL == node)     /* 所有兄弟节点已经处理完成,说明父亲节点也处理完成 */
    {
        /* 3. 父亲节点出栈 */
        top = stack_pop(stack);
        if (NULL == top) {
            *len += len2;
            log_error(xml->log, "Stack pop failed!");
            return NULL;
        }

        /* 4. 打印父亲节点结束标志 */
        if (xml_has_child(top)) {
            depth = stack_depth(stack);
            level = depth + 1;
            while (level > 1)
            {
                /* fprintf(fp, "\t"); */
                len2++;
                level--;
            }
            /* fprintf(fp, "</%s>\n", top->name); */
            len2 += (top->name.len + 4);
        }

        if (stack_empty(stack)) {
            *len += len2;
            return NULL;    /* 处理完成 */
        }

        /* 5. 选择父亲的兄弟节点 */
        node = top->next;
    }

    *len += len2;
    return node;
}
Ejemplo n.º 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;
}