Beispiel #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;
}
Beispiel #2
0
static int
medin_doconvert( xml *node, fields *info, xml_convert *c, int nc, int *found )
{
	int i, fstatus;
	char *d;
	*found = 0;
	if ( !xml_has_value( node ) ) return BIBL_OK;
	d = xml_value_cstr( node );
	for ( i=0; i<nc && *found==0; ++i ) {
		if ( c[i].a==NULL ) {
			if ( xml_tag_matches( node, c[i].in ) ) {
				*found = 1;
				fstatus = fields_add( info, c[i].out, d, c[i].level );
				if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
			}
		} else {
			if ( xml_tag_has_attribute( node, c[i].in, c[i].a, c[i].aval ) ) {
				*found = 1;
				fstatus = fields_add( info, c[i].out, d, c[i].level );
				if ( fstatus!=FIELDS_OK ) return BIBL_ERR_MEMERR;
			}
		}
	
	}
	return BIBL_OK;
}
Beispiel #3
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;
}
Beispiel #4
0
/* <ArticleTitle>Mechanism and.....</ArticleTitle>
 */
static int
medin_articletitle( xml *node, fields *info )
{
	int fstatus, status = BIBL_OK;
	if ( xml_has_value( node ) ) {
		fstatus = fields_add( info, "TITLE", xml_value_cstr( node ), 0 );
		if ( fstatus!=FIELDS_OK ) status = BIBL_ERR_MEMERR;
	}
	return status;
}
Beispiel #5
0
/******************************************************************************
 **函数名称: xml_add_child
 **功    能: 给指定节点添加孩子节点
 **输入参数:
 **     node: 需要添加孩子节点的节点
 **     name: 孩子节点名
 **     value: 孩子节点值
 **输出参数:
 **返    回: 新增节点的地址
 **实现描述: 
 **注意事项: 
 **     1. 新建孩子节点
 **     2. 将孩子加入子节点链表尾
 **作    者: # Qifeng.zou # 2013.03.01 #
 ******************************************************************************/
xml_node_t *xml_add_child(xml_tree_t *xml, xml_node_t *node, const char *name, const char *value)
{
    xml_node_t *child = NULL;

    if (xml_is_attr(node)) {
        log_error(xml->log, "Can't add child for attribute node![%s]", node->name.str);
        return NULL;
    }
#if defined(__XML_EITHER_CHILD_OR_VALUE__)
    else if (xml_has_value(node)) {
        log_error(xml->log, "Can't add child for the node which has value![%s]", node->name.str);
        return NULL;
    }
#endif /*__XML_EITHER_CHILD_OR_VALUE__*/

    /* 1. 新建孩子节点 */
    child = xml_node_creat_ext(xml, XML_NODE_CHILD, name, value);
    if (NULL == child) {
        log_error(xml->log, "Create node failed![%s]", name);
        return NULL;
    }

    child->parent = node;

    /* 2. 将孩子加入子节点链表尾 */    
    if (NULL == node->tail) {            /* 没有孩子&属性节点 */
        node->child = child;
    }
    else {
        node->tail->next = child;
    }

    node->tail = child;

    xml_set_child_flag(node);
    
    return child;
}
Beispiel #6
0
/* <Journal>
 *    <ISSN>0027-8424</ISSN>
 *    <JournalIssue PrintYN="Y">
 *       <Volume>100</Volume>
 *       <Issue>21</Issue>
 *       <PubDate>
 *          <Year>2003</Year>
 *          <Month>Oct</Month>
 *          <Day>14</Day>
 *       </PubDate>
 *    </Journal Issue>
 * </Journal>
 *
 * or....
 *
 * <Journal>
 *    <ISSN IssnType="Print">0735-0414</ISSN>
 *    <JournalIssue CitedMedium="Print">
 *        <Volume>38</Volume>
 *        <Issue>1</Issue>
 *        <PubDate>
 *            <MedlineDate>2003 Jan-Feb</MedlineDate>
 *        </PubDate>
 *    </JournalIssue>
 *    <Title>Alcohol and alcoholism (Oxford, Oxfordshire)  </Title>
 *    <ISOAbbreviation>Alcohol Alcohol.</ISOAbbreviation>
 * </Journal>
 */
static int
medin_journal1( xml *node, fields *info )
{
	xml_convert c[] = {
		{ "Title",           NULL, NULL, "TITLE",          1 },
		{ "ISOAbbreviation", NULL, NULL, "SHORTTITLE",     1 },
		{ "ISSN",            NULL, NULL, "ISSN",           1 },
		{ "Volume",          NULL, NULL, "VOLUME",         1 },
		{ "Issue",           NULL, NULL, "ISSUE",          1 },
		{ "Year",            NULL, NULL, "PARTDATE:YEAR",  1 },
		{ "Month",           NULL, NULL, "PARTDATE:MONTH", 1 },
		{ "Day",             NULL, NULL, "PARTDATE:DAY",   1 },
	};
	int nc = sizeof( c ) / sizeof( c[0] ), status, found;
	if ( xml_has_value( node ) ) {
		status = medin_doconvert( node, info, c, nc, &found );
		if ( status!=BIBL_OK ) return status;
		if ( !found ) {
			if ( xml_tag_matches( node, "MedlineDate" ) ) {
				status = medin_medlinedate( info, xml_value_cstr( node ), 1 );
				if ( status!=BIBL_OK ) return status;
			}
			if ( xml_tag_matches( node, "Language" ) ) {
				status = medin_language( node, info, 1 );
				if ( status!=BIBL_OK ) return status;
			}
		}
	}
	if ( node->down ) {
		status = medin_journal1( node->down, info );
		if ( status!=BIBL_OK ) return status;
	}
	if ( node->next ) {
		status = medin_journal1( node->next, info );
		if ( status!=BIBL_OK ) return status;
	}
	return BIBL_OK;
}