⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ne_xml.c

📁 linux subdivision ying gai ke yi le ba
💻 C
📖 第 1 页 / 共 2 页
字号:
        if (state > 0)        elm->state = state;    else if (state == NE_XML_DECLINE)        /* prune this branch. */        p->prune++;    else /* state == NE_XML_ABORT */        p->valid = 0;}/* Destroys an element structure. */static void destroy_element(struct element *elm) {    struct namespace *this_ns, *next_ns;    ne_free(elm->name);    /* Free the namespaces */    this_ns = elm->nspaces;    while (this_ns != NULL) {	next_ns = this_ns->next;	ne_free(this_ns->name);	ne_free(this_ns->uri);	ne_free(this_ns);	this_ns = next_ns;    };    if (elm->default_ns)        ne_free(elm->default_ns);    ne_free(elm);}/* cdata SAX callback */static void char_data(void *userdata, const ne_xml_char *data, int len) {    ne_xml_parser *p = userdata;    struct element *elm = p->current;    if (!p->valid || p->prune) return;        if (elm->handler->cdata_cb &&         elm->handler->cdata_cb(elm->handler->userdata, elm->state, data, len)) {        NE_DEBUG(NE_DBG_XML, "Cdata callback failed.\n");        p->valid = 0;    }        }/* Called with the end of an element */static void end_element(void *userdata, const ne_xml_char *name) {    ne_xml_parser *p = userdata;    struct element *elm = p->current;    if (!p->valid) return;	    if (p->prune) {        if (p->prune-- > 1) return;    } else if (elm->handler->endelm_cb &&                elm->handler->endelm_cb(elm->handler->userdata, elm->state,                                       elm->nspace, elm->name)) {        NE_DEBUG(NE_DBG_XML, "XML: end-element for %d failed.\n", elm->state);        p->valid = 0;    }        NE_DEBUG(NE_DBG_XMLPARSE, "XML: end-element (%d, {%s, %s})\n",             elm->state, elm->nspace, elm->name);    /* move back up the tree */    p->current = elm->parent;    p->prune = 0;    destroy_element(elm);}/* Find a namespace definition for 'prefix' in given element, where * length of prefix is 'pfxlen'.  Returns the URI or NULL. */static const char *resolve_nspace(const struct element *elm,                                   const char *prefix, size_t pfxlen){    const struct element *s;    /* Search up the tree. */    for (s = elm; s != NULL; s = s->parent) {	const struct namespace *ns;	/* Iterate over defined spaces on this node. */	for (ns = s->nspaces; ns != NULL; ns = ns->next) {	    if (strlen(ns->name) == pfxlen && 		memcmp(ns->name, prefix, pfxlen) == 0)		return ns->uri;	}    }    return NULL;}ne_xml_parser *ne_xml_create(void) {    ne_xml_parser *p = ne_calloc(sizeof *p);    /* Initialize other stuff */    p->valid = 1;    /* Placeholder for the root element */    p->current = p->root = ne_calloc(sizeof *p->root);    p->root->default_ns = "";    p->root->state = 0;    strcpy(p->error, _("Unknown error"));#ifdef HAVE_EXPAT    p->parser = XML_ParserCreate(NULL);    if (p->parser == NULL) {	abort();    }    XML_SetElementHandler(p->parser, start_element, end_element);    XML_SetCharacterDataHandler(p->parser, char_data);    XML_SetUserData(p->parser, (void *) p);    XML_SetXmlDeclHandler(p->parser, decl_handler);#else    p->parser = xmlCreatePushParserCtxt(&sax_handler, 					(void *)p, NULL, 0, NULL);    if (p->parser == NULL) {	abort();    }    p->parser->replaceEntities = 1;#endif    return p;}void ne_xml_push_handler(ne_xml_parser *p,			 ne_xml_startelm_cb *startelm_cb, 			 ne_xml_cdata_cb *cdata_cb, 			 ne_xml_endelm_cb *endelm_cb,			 void *userdata){    struct handler *hand = ne_calloc(sizeof(struct handler));    hand->startelm_cb = startelm_cb;    hand->cdata_cb = cdata_cb;    hand->endelm_cb = endelm_cb;    hand->userdata = userdata;    /* If this is the first handler registered, update the     * base pointer too. */    if (p->top_handlers == NULL) {	p->root->handler = hand;	p->top_handlers = hand;    } else {	p->top_handlers->next = hand;	p->top_handlers = hand;    }}void ne_xml_parse_v(void *userdata, const char *block, size_t len) {    ne_xml_parser *p = userdata;    /* FIXME: The two XML parsers break all our nice abstraction by     * choosing different char *'s. The swine. This cast will come     * back and bite us someday, no doubt. */    ne_xml_parse(p, block, len);}/* Parse the given block of input of length len */void ne_xml_parse(ne_xml_parser *p, const char *block, size_t len) {    int ret, flag;    /* duck out if it's broken */    if (!p->valid) {	NE_DEBUG(NE_DBG_XML, "Not parsing %" NE_FMT_SIZE_T " bytes.\n", 		 len);	return;    }    if (len == 0) {	flag = -1;	block = "";	NE_DEBUG(NE_DBG_XML, "Got 0-length buffer, end of document.\n");    } else {		NE_DEBUG(NE_DBG_XML, "Parsing %" NE_FMT_SIZE_T " length buffer.\n",		 len);	flag = 0;    }    /* Note, don't write a parser error if !p->valid, since an error     * will already have been written in that case. */#ifdef HAVE_EXPAT    ret = XML_Parse(p->parser, block, len, flag);    NE_DEBUG(NE_DBG_XMLPARSE, "XML_Parse returned %d\n", ret);    if (ret == 0 && p->valid) {	ne_snprintf(p->error, ERR_SIZE,		    "XML parse error at line %d: %s", 		    XML_GetCurrentLineNumber(p->parser),		    XML_ErrorString(XML_GetErrorCode(p->parser)));	p->valid = 0;    }#else    ret = xmlParseChunk(p->parser, block, len, flag);    NE_DEBUG(NE_DBG_XMLPARSE, "xmlParseChunk returned %d\n", ret);    /* Parse errors are normally caught by the sax_error() callback,     * which clears p->valid. */    if (p->parser->errNo && p->valid) {	ne_snprintf(p->error, ERR_SIZE, "XML parse error at line %d.", 		    ne_xml_currentline(p));	p->valid = 0;    }#endif}int ne_xml_valid(ne_xml_parser *p){    return p->valid;}void ne_xml_destroy(ne_xml_parser *p) {    struct element *elm, *parent;    struct handler *hand, *next;    /* Free up the handlers on the stack: the root element has the     * pointer to the base of the handler stack. */    for (hand = p->root->handler; hand!=NULL; hand=next) {	next = hand->next;	ne_free(hand);    }    /* Clean up remaining elements */    for (elm = p->current; elm != p->root; elm = parent) {	parent = elm->parent;	destroy_element(elm);    }    /* free root element */    ne_free(p->root);#ifdef HAVE_EXPAT    XML_ParserFree(p->parser);    if (p->encoding) ne_free(p->encoding);#else    xmlFreeParserCtxt(p->parser);#endif    ne_free(p);}void ne_xml_set_error(ne_xml_parser *p, const char *msg){    ne_snprintf(p->error, ERR_SIZE, "%s", msg);}#ifdef HAVE_LIBXMLstatic void sax_error(void *ctx, const char *msg, ...){    ne_xml_parser *p = ctx;    va_list ap;    char buf[1024];    va_start(ap, msg);    ne_vsnprintf(buf, 1024, msg, ap);    va_end(ap);    ne_snprintf(p->error, ERR_SIZE, 		_("XML parse error at line %d: %s."),		p->parser->input->line, buf);    p->valid = 0;}#endifconst char *ne_xml_get_error(ne_xml_parser *p){    return p->error;}const char *ne_xml_get_attr(ne_xml_parser *p, const char **attrs, 		const char *nspace, const char *name){    int n;    for (n = 0; attrs[n] != NULL; n += 2) {	char *pnt = strchr(attrs[n], ':');	if (!nspace && !pnt && strcmp(attrs[n], name) == 0) {	    return attrs[n+1];	} else if (nspace && pnt) {	    /* If a namespace is given, and the local part matches,	     * then resolve the namespace and compare that too. */	    if (strcmp(pnt + 1, name) == 0) {		const char *uri = resolve_nspace(p->current, 						 attrs[n], pnt - attrs[n]);		if (uri && strcmp(uri, nspace) == 0)		    return attrs[n+1];	    }	}    }    return NULL;}int ne_xml_mapid(const struct ne_xml_idmap map[], size_t maplen,                 const char *nspace, const char *name){    size_t n;        for (n = 0; n < maplen; n++)        if (strcmp(name, map[n].name) == 0 &&            strcmp(nspace, map[n].nspace) == 0)            return map[n].id;        return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -