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

📄 pattern.c

📁 xml开源解析代码.版本为libxml2-2.6.29,可支持GB3212.网络消息发送XML时很有用.
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (step.flags & XML_STREAM_STEP_ROOT)	    goto stream_next;	desc = step.flags & XML_STREAM_STEP_DESC;	if (stream->flags & XML_PATTERN_NOTPATTERN) {	    /*	    * Re/enter the expression if it is a "descendant" one,	    * or if we are at the 1st level of evaluation.	    */	    	    if (stream->level == 1) {		if (XML_STREAM_XS_IDC(stream)) {		    /*		    * XS-IDC: The missing "self::node()" will always		    * match the first given node.		    */		    goto stream_next;		} else		    goto compare;	    }	    	    /*	    * A "//" is always reentrant.	    */	    if (desc)		goto compare;	    /*	    * XS-IDC: Process the 2nd level, since the missing	    * "self::node()" is responsible for the 2nd level being	    * the real start level.	    	    */	    	    if ((stream->level == 2) && XML_STREAM_XS_IDC(stream))		goto compare;	    goto stream_next;	}	compare:	/*	* Check expected node-type.	*/	if (step.nodeType != nodeType) {	    if (nodeType == XML_ATTRIBUTE_NODE)		goto stream_next;	    else if (step.nodeType != XML_STREAM_ANY_NODE)		goto stream_next;	     	}	/*	* Compare local/namespace-name.	*/	match = 0;	if (step.nodeType == XML_STREAM_ANY_NODE) {	    match = 1;	} else if (step.name == NULL) {	    if (step.ns == NULL) {		/*		* This lets through all elements/attributes.		*/		match = 1;	    } else if (ns != NULL)		match = xmlStrEqual(step.ns, ns);	} else if (((step.ns != NULL) == (ns != NULL)) &&	    (name != NULL) &&	    (step.name[0] == name[0]) &&	    xmlStrEqual(step.name, name) &&	    ((step.ns == ns) || xmlStrEqual(step.ns, ns)))	{	    match = 1;	    	}	    	final = step.flags & XML_STREAM_STEP_FINAL;	if (match) {	    	    if (final)		ret = 1;	    else		xmlStreamCtxtAddState(stream, 1, stream->level);	    if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) {		/*		* Check if we have a special case like "foo//.", where		* "foo" is selected as well.		*/		ret = 1;	    }	}	if (((comp->flags & XML_STREAM_DESC) == 0) &&	    ((! match) || final))  {	    /*	    * Mark this expression as blocked for any evaluation at	    * deeper levels.	    */	    stream->blockLevel = stream->level;	}stream_next:        stream = stream->next;    } /* while stream != NULL */     if (err > 0)        ret = -1;#ifdef DEBUG_STREAMING    xmlDebugStreamCtxt(orig, ret);#endif    return(ret);}/** * xmlStreamPush: * @stream: the stream context * @name: the current name * @ns: the namespace name * * Push new data onto the stream. NOTE: if the call xmlPatterncompile() * indicated a dictionary, then strings for name and ns will be expected * to come from the dictionary. * Both @name and @ns being NULL means the / i.e. the root of the document. * This can also act as a reset. * Otherwise the function will act as if it has been given an element-node. * * Returns: -1 in case of error, 1 if the current state in the stream is a *    match and 0 otherwise. */intxmlStreamPush(xmlStreamCtxtPtr stream,              const xmlChar *name, const xmlChar *ns) {    return (xmlStreamPushInternal(stream, name, ns, (int) XML_ELEMENT_NODE));}/** * xmlStreamPushNode: * @stream: the stream context * @name: the current name * @ns: the namespace name * @nodeType: the type of the node being pushed * * Push new data onto the stream. NOTE: if the call xmlPatterncompile() * indicated a dictionary, then strings for name and ns will be expected * to come from the dictionary. * Both @name and @ns being NULL means the / i.e. the root of the document. * This can also act as a reset. * Different from xmlStreamPush() this function can be fed with nodes of type: * element-, attribute-, text-, cdata-section-, comment- and * processing-instruction-node. * * Returns: -1 in case of error, 1 if the current state in the stream is a *    match and 0 otherwise. */intxmlStreamPushNode(xmlStreamCtxtPtr stream,		  const xmlChar *name, const xmlChar *ns,		  int nodeType){    return (xmlStreamPushInternal(stream, name, ns,	nodeType));}/*** xmlStreamPushAttr:* @stream: the stream context* @name: the current name* @ns: the namespace name** Push new attribute data onto the stream. NOTE: if the call xmlPatterncompile()* indicated a dictionary, then strings for name and ns will be expected* to come from the dictionary.* Both @name and @ns being NULL means the / i.e. the root of the document.* This can also act as a reset.* Otherwise the function will act as if it has been given an attribute-node.** Returns: -1 in case of error, 1 if the current state in the stream is a*    match and 0 otherwise.*/intxmlStreamPushAttr(xmlStreamCtxtPtr stream,		  const xmlChar *name, const xmlChar *ns) {    return (xmlStreamPushInternal(stream, name, ns, (int) XML_ATTRIBUTE_NODE));}/** * xmlStreamPop: * @stream: the stream context * * push one level from the stream. * * Returns: -1 in case of error, 0 otherwise. */intxmlStreamPop(xmlStreamCtxtPtr stream) {    int i, lev;        if (stream == NULL)        return(-1);    while (stream != NULL) {	/*	* Reset block-level.	*/	if (stream->blockLevel == stream->level)	    stream->blockLevel = -1;	stream->level--;	if (stream->level < 0)	    return(-1);			/*	 * Check evolution of existing states	 */		for (i = stream->nbState -1; i >= 0; i--) {	    /* discard obsoleted states */	    lev = stream->states[(2 * i) + 1];	    if (lev > stream->level)		stream->nbState--;	    if (lev <= stream->level)		break;	}	stream = stream->next;    }    return(0);}/** * xmlStreamWantsAnyNode: * @streamCtxt: the stream context * * Query if the streaming pattern additionally needs to be fed with * text-, cdata-section-, comment- and processing-instruction-nodes. * If the result is 0 then only element-nodes and attribute-nodes * need to be pushed. * * Returns: 1 in case of need of nodes of the above described types, *          0 otherwise. -1 on API errors. */intxmlStreamWantsAnyNode(xmlStreamCtxtPtr streamCtxt){        if (streamCtxt == NULL)	return(-1);    while (streamCtxt != NULL) {	if (streamCtxt->comp->flags & XML_STREAM_FINAL_IS_ANY_NODE)		    return(1);	streamCtxt = streamCtxt->next;    }    return(0);}/************************************************************************ *									* *			The public interfaces				* *									* ************************************************************************//** * xmlPatterncompile: * @pattern: the pattern to compile * @dict: an optional dictionary for interned strings * @flags: compilation flags, see xmlPatternFlags * @namespaces: the prefix definitions, array of [URI, prefix] or NULL * * Compile a pattern. * * Returns the compiled form of the pattern or NULL in case of error */xmlPatternPtrxmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags,                  const xmlChar **namespaces) {    xmlPatternPtr ret = NULL, cur;    xmlPatParserContextPtr ctxt = NULL;    const xmlChar *or, *start;    xmlChar *tmp = NULL;    int type = 0;    int streamable = 1;    if (pattern == NULL)        return(NULL);    start = pattern;    or = start;    while (*or != 0) {	tmp = NULL;	while ((*or != 0) && (*or != '|')) or++;        if (*or == 0)	    ctxt = xmlNewPatParserContext(start, dict, namespaces);	else {	    tmp = xmlStrndup(start, or - start);	    if (tmp != NULL) {		ctxt = xmlNewPatParserContext(tmp, dict, namespaces);	    }	    or++;	}	if (ctxt == NULL) goto error;		cur = xmlNewPattern();	if (cur == NULL) goto error;	/*	* Assign string dict.	*/	if (dict) {	    	    cur->dict = dict;	    xmlDictReference(dict);	}	if (ret == NULL)	    ret = cur;	else {	    cur->next = ret->next;	    ret->next = cur;	}	cur->flags = flags;	ctxt->comp = cur;	if (XML_STREAM_XS_IDC(cur))	    xmlCompileIDCXPathPath(ctxt);	else	    xmlCompilePathPattern(ctxt);	if (ctxt->error != 0)	    goto error;	xmlFreePatParserContext(ctxt);	ctxt = NULL;        if (streamable) {	    if (type == 0) {	        type = cur->flags & (PAT_FROM_ROOT | PAT_FROM_CUR);	    } else if (type == PAT_FROM_ROOT) {	        if (cur->flags & PAT_FROM_CUR)		    streamable = 0;	    } else if (type == PAT_FROM_CUR) {	        if (cur->flags & PAT_FROM_ROOT)		    streamable = 0;	    }	}	if (streamable)	    xmlStreamCompile(cur);	if (xmlReversePattern(cur) < 0)	    goto error;	if (tmp != NULL) {	    xmlFree(tmp);	    tmp = NULL;	}	start = or;    }    if (streamable == 0) {        cur = ret;	while (cur != NULL) {	    if (cur->stream != NULL) {		xmlFreeStreamComp(cur->stream);		cur->stream = NULL;	    }	    cur = cur->next;	}    }    return(ret);error:    if (ctxt != NULL) xmlFreePatParserContext(ctxt);    if (ret != NULL) xmlFreePattern(ret);    if (tmp != NULL) xmlFree(tmp);    return(NULL);}/** * xmlPatternMatch: * @comp: the precompiled pattern * @node: a node * * Test whether the node matches the pattern * * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure */intxmlPatternMatch(xmlPatternPtr comp, xmlNodePtr node){    int ret = 0;    if ((comp == NULL) || (node == NULL))        return(-1);    while (comp != NULL) {        ret = xmlPatMatch(comp, node);	if (ret != 0)	    return(ret);	comp = comp->next;    }    return(ret);}/** * xmlPatternGetStreamCtxt: * @comp: the precompiled pattern * * Get a streaming context for that pattern * Use xmlFreeStreamCtxt to free the context. * * Returns a pointer to the context or NULL in case of failure */xmlStreamCtxtPtrxmlPatternGetStreamCtxt(xmlPatternPtr comp){    xmlStreamCtxtPtr ret = NULL, cur;    if ((comp == NULL) || (comp->stream == NULL))        return(NULL);    while (comp != NULL) {        if (comp->stream == NULL)	    goto failed;	cur = xmlNewStreamCtxt(comp->stream);	if (cur == NULL)	    goto failed;	if (ret == NULL)	    ret = cur;	else {	    cur->next = ret->next;	    ret->next = cur;	}	cur->flags = comp->flags;	comp = comp->next;    }    return(ret);failed:    xmlFreeStreamCtxt(ret);    return(NULL);}/** * xmlPatternStreamable: * @comp: the precompiled pattern * * Check if the pattern is streamable i.e. xmlPatternGetStreamCtxt() * should work. * * Returns 1 if streamable, 0 if not and -1 in case of error. */intxmlPatternStreamable(xmlPatternPtr comp) {    if (comp == NULL)        return(-1);    while (comp != NULL) {        if (comp->stream == NULL)	    return(0);	comp = comp->next;    }    return(1);}/** * xmlPatternMaxDepth: * @comp: the precompiled pattern * * Check the maximum depth reachable by a pattern * * Returns -2 if no limit (using //), otherwise the depth, *         and -1 in case of error */intxmlPatternMaxDepth(xmlPatternPtr comp) {    int ret = 0, i;    if (comp == NULL)        return(-1);    while (comp != NULL) {        if (comp->stream == NULL)	    return(-1);	for (i = 0;i < comp->stream->nbStep;i++)	    if (comp->stream->steps[i].flags & XML_STREAM_STEP_DESC)	        return(-2);	if (comp->stream->nbStep > ret)	    ret = comp->stream->nbStep;	comp = comp->next;    }    return(ret);}/** * xmlPatternMinDepth: * @comp: the precompiled pattern * * Check the minimum depth reachable by a pattern, 0 mean the / or . are * part of the set. * * Returns -1 in case of error otherwise the depth, *          */intxmlPatternMinDepth(xmlPatternPtr comp) {    int ret = 12345678;    if (comp == NULL)        return(-1);    while (comp != NULL) {        if (comp->stream == NULL)	    return(-1);	if (comp->stream->nbStep < ret)	    ret = comp->stream->nbStep;	if (ret == 0)	    return(0);	comp = comp->next;    }    return(ret);}/** * xmlPatternFromRoot: * @comp: the precompiled pattern * * Check if the pattern must be looked at from the root. * * Returns 1 if true, 0 if false and -1 in case of error */intxmlPatternFromRoot(xmlPatternPtr comp) {    if (comp == NULL)        return(-1);    while (comp != NULL) {        if (comp->stream == NULL)	    return(-1);	if (comp->flags & PAT_FROM_ROOT)	    return(1);	comp = comp->next;    }    return(0);}#define bottom_pattern#include "elfgcchack.h"#endif /* LIBXML_PATTERN_ENABLED */

⌨️ 快捷键说明

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