Exemple #1
0
/******************************************************************************
 **函数名称: xml_mark_get_attr
 **功    能: 解析有属性的标签
 **输入参数:
 **     
 **     stack: XML栈
 **     parse: 解析文件缓存信息
 **输出参数:
 **返    回: 0: 成功  !0: 失败
 **实现描述: 
 **注意事项: 
 **     1. 属性值可使用双引号或单引号确定属性值范围
 **     2. 转义符号的转换对应关系如下:
 **       &lt;    <    小于
 **       &gt;    >    大于
 **       &amp;   &    和号
 **       &apos;  '    单引号
 **       &quot;  "    引号
 **作    者: # 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;
}
Exemple #2
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;
}