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

📄 pattern.c.svn-base

📁 这是一个用于解析xml文件的类库。使用这个类库
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/* * pattern.c: Implemetation of selectors for nodes * * Reference: *   http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/ *   to some extent  *   http://www.w3.org/TR/1999/REC-xml-19991116 * * See Copyright for the status of this software. * * daniel@veillard.com */#define IN_LIBXML#include "libxml.h"#include <string.h>#include <libxml/xmlmemory.h>#include <libxml/tree.h>#include <libxml/hash.h>#include <libxml/dict.h>#include <libxml/xmlerror.h>#include <libxml/parserInternals.h>#include <libxml/pattern.h>#ifdef LIBXML_PATTERN_ENABLED#define ERROR(a, b, c, d)#define ERROR5(a, b, c, d, e)/* * Types are private: */typedef enum {    XML_OP_END=0,    XML_OP_ROOT,    XML_OP_ELEM,    XML_OP_CHILD,    XML_OP_ATTR,    XML_OP_PARENT,    XML_OP_ANCESTOR,    XML_OP_NS,    XML_OP_ALL} xmlPatOp;typedef struct _xmlStepOp xmlStepOp;typedef xmlStepOp *xmlStepOpPtr;struct _xmlStepOp {    xmlPatOp op;    const xmlChar *value;    const xmlChar *value2;};struct _xmlPattern {    void *data;    		/* the associated template */    struct _xmlPattern *next; /* siblings */    const xmlChar *pattern;	/* the pattern */    /* TODO fix the statically allocated size steps[] */    int nbStep;    int maxStep;    xmlStepOp steps[10];        /* ops for computation */};typedef struct _xmlPatParserContext xmlPatParserContext;typedef xmlPatParserContext *xmlPatParserContextPtr;struct _xmlPatParserContext {    const xmlChar *cur;			/* the current char being parsed */    const xmlChar *base;		/* the full expression */    int	           error;		/* error code */    xmlDictPtr     dict;		/* the dictionnary if any */    xmlPatternPtr  comp;		/* the result */    xmlNodePtr     elem;		/* the current node if any */        const xmlChar **namespaces;		/* the namespaces definitions */    int   nb_namespaces;		/* the number of namespaces */};/************************************************************************ * 									* * 			Type functions 					* * 									* ************************************************************************//** * xmlNewPattern: * * Create a new XSLT Pattern * * Returns the newly allocated xmlPatternPtr or NULL in case of error */static xmlPatternPtrxmlNewPattern(void) {    xmlPatternPtr cur;    cur = (xmlPatternPtr) xmlMalloc(sizeof(xmlPattern));    if (cur == NULL) {	ERROR(NULL, NULL, NULL,		"xmlNewPattern : malloc failed\n");	return(NULL);    }    memset(cur, 0, sizeof(xmlPattern));    cur->maxStep = 10;    return(cur);}/** * xmlFreePattern: * @comp:  an XSLT comp * * Free up the memory allocated by @comp */voidxmlFreePattern(xmlPatternPtr comp) {    xmlStepOpPtr op;    int i;    if (comp == NULL)	return;    if (comp->pattern != NULL)	xmlFree((xmlChar *)comp->pattern);    for (i = 0;i < comp->nbStep;i++) {	op = &comp->steps[i];	if (op->value != NULL)	    xmlFree((xmlChar *) op->value);	if (op->value2 != NULL)	    xmlFree((xmlChar *) op->value2);    }    memset(comp, -1, sizeof(xmlPattern));    xmlFree(comp);}/** * xmlFreePatternList: * @comp:  an XSLT comp list * * Free up the memory allocated by all the elements of @comp */voidxmlFreePatternList(xmlPatternPtr comp) {    xmlPatternPtr cur;    while (comp != NULL) {	cur = comp;	comp = comp->next;	xmlFreePattern(cur);    }}/** * xmlNewPatParserContext: * @pattern:  the pattern context * @dict:  the inherited dictionnary or NULL * @namespaces: the prefix definitions, array of [URI, prefix] or NULL * * Create a new XML pattern parser context * * Returns the newly allocated xmlPatParserContextPtr or NULL in case of error */static xmlPatParserContextPtrxmlNewPatParserContext(const xmlChar *pattern, xmlDictPtr dict,                       const xmlChar **namespaces) {    xmlPatParserContextPtr cur;    if (pattern == NULL)        return(NULL);    cur = (xmlPatParserContextPtr) xmlMalloc(sizeof(xmlPatParserContext));    if (cur == NULL) {	ERROR(NULL, NULL, NULL,		"xmlNewPatParserContext : malloc failed\n");	return(NULL);    }    memset(cur, 0, sizeof(xmlPatParserContext));    cur->dict = dict;    cur->cur = pattern;    cur->base = pattern;    if (namespaces != NULL) {        int i;	for (i = 0;namespaces[2 * i] != NULL;i++);        cur->nb_namespaces = i;    } else {        cur->nb_namespaces = 0;    }    cur->namespaces = namespaces;    return(cur);}/** * xmlFreePatParserContext: * @ctxt:  an XSLT parser context * * Free up the memory allocated by @ctxt */static voidxmlFreePatParserContext(xmlPatParserContextPtr ctxt) {    if (ctxt == NULL)	return;    memset(ctxt, -1, sizeof(xmlPatParserContext));    xmlFree(ctxt);}/** * xmlPatternAdd: * @comp:  the compiled match expression * @op:  an op * @value:  the first value * @value2:  the second value * * Add an step to an XSLT Compiled Match * * Returns -1 in case of failure, 0 otherwise. */static intxmlPatternAdd(xmlPatParserContextPtr ctxt ATTRIBUTE_UNUSED,                xmlPatternPtr comp,                xmlPatOp op, xmlChar * value, xmlChar * value2){    if (comp->nbStep >= 10) {        ERROR(ctxt, NULL, NULL,                         "xmlPatternAdd: overflow\n");        return (-1);    }    comp->steps[comp->nbStep].op = op;    comp->steps[comp->nbStep].value = value;    comp->steps[comp->nbStep].value2 = value2;    comp->nbStep++;    return (0);}#if 0/** * xsltSwapTopPattern: * @comp:  the compiled match expression * * reverse the two top steps. */static voidxsltSwapTopPattern(xmlPatternPtr comp) {    int i;    int j = comp->nbStep - 1;    if (j > 0) {	register const xmlChar *tmp;	register xmlPatOp op;	i = j - 1;	tmp = comp->steps[i].value;	comp->steps[i].value = comp->steps[j].value;	comp->steps[j].value = tmp;	tmp = comp->steps[i].value2;	comp->steps[i].value2 = comp->steps[j].value2;	comp->steps[j].value2 = tmp;	op = comp->steps[i].op;	comp->steps[i].op = comp->steps[j].op;	comp->steps[j].op = op;    }}#endif/** * xmlReversePattern: * @comp:  the compiled match expression * * reverse all the stack of expressions */static voidxmlReversePattern(xmlPatternPtr comp) {    int i = 0;    int j = comp->nbStep - 1;    while (j > i) {	register const xmlChar *tmp;	register xmlPatOp op;	tmp = comp->steps[i].value;	comp->steps[i].value = comp->steps[j].value;	comp->steps[j].value = tmp;	tmp = comp->steps[i].value2;	comp->steps[i].value2 = comp->steps[j].value2;	comp->steps[j].value2 = tmp;	op = comp->steps[i].op;	comp->steps[i].op = comp->steps[j].op;	comp->steps[j].op = op;	j--;	i++;    }    comp->steps[comp->nbStep++].op = XML_OP_END;}/************************************************************************ * 									* * 		The interpreter for the precompiled patterns		* * 									* ************************************************************************//** * xmlPatMatch: * @comp: the precompiled pattern * @node: a node * * Test wether the node matches the pattern * * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure */static intxmlPatMatch(xmlPatternPtr comp, xmlNodePtr node) {    int i;    xmlStepOpPtr step;    if ((comp == NULL) || (node == NULL)) return(-1);    for (i = 0;i < comp->nbStep;i++) {	step = &comp->steps[i];	switch (step->op) {            case XML_OP_END:		return(1);            case XML_OP_ROOT:		if ((node->type == XML_DOCUMENT_NODE) ||#ifdef LIBXML_DOCB_ENABLED		    (node->type == XML_DOCB_DOCUMENT_NODE) ||#endif		    (node->type == XML_HTML_DOCUMENT_NODE))		    continue;		return(0);            case XML_OP_ELEM:		if (node->type != XML_ELEMENT_NODE)		    return(0);		if (step->value == NULL)		    continue;		if (step->value[0] != node->name[0])		    return(0);		if (!xmlStrEqual(step->value, node->name))		    return(0);		/* Namespace test */		if (node->ns == NULL) {		    if (step->value2 != NULL)			return(0);		} else if (node->ns->href != NULL) {		    if (step->value2 == NULL)			return(0);		    if (!xmlStrEqual(step->value2, node->ns->href))			return(0);		}		continue;            case XML_OP_CHILD: {		xmlNodePtr lst;		if ((node->type != XML_ELEMENT_NODE) &&		    (node->type != XML_DOCUMENT_NODE) &&#ifdef LIBXML_DOCB_ENABLED		    (node->type != XML_DOCB_DOCUMENT_NODE) &&#endif		    (node->type != XML_HTML_DOCUMENT_NODE))		    return(0);		lst = node->children;		if (step->value != NULL) {		    while (lst != NULL) {			if ((lst->type == XML_ELEMENT_NODE) &&			    (step->value[0] == lst->name[0]) &&			    (xmlStrEqual(step->value, lst->name)))			    break;			lst = lst->next;		    }		    if (lst != NULL)			continue;		}		return(0);	    }            case XML_OP_ATTR:		if (node->type != XML_ATTRIBUTE_NODE)		    return(0);		if (step->value != NULL) {		    if (step->value[0] != node->name[0])			return(0);		    if (!xmlStrEqual(step->value, node->name))			return(0);		}		/* Namespace test */		if (node->ns == NULL) {		    if (step->value2 != NULL)			return(0);		} else if (step->value2 != NULL) {		    if (!xmlStrEqual(step->value2, node->ns->href))			return(0);		}		continue;            case XML_OP_PARENT:		if ((node->type == XML_DOCUMENT_NODE) ||		    (node->type == XML_HTML_DOCUMENT_NODE) ||#ifdef LIBXML_DOCB_ENABLED		    (node->type == XML_DOCB_DOCUMENT_NODE) ||#endif		    (node->type == XML_NAMESPACE_DECL))		    return(0);		node = node->parent;		if (node == NULL)		    return(0);		if (step->value == NULL)		    continue;		if (step->value[0] != node->name[0])		    return(0);		if (!xmlStrEqual(step->value, node->name))		    return(0);		/* Namespace test */		if (node->ns == NULL) {		    if (step->value2 != NULL)			return(0);		} else if (node->ns->href != NULL) {		    if (step->value2 == NULL)			return(0);		    if (!xmlStrEqual(step->value2, node->ns->href))			return(0);		}		continue;            case XML_OP_ANCESTOR:		/* TODO: implement coalescing of ANCESTOR/NODE ops */		if (step->value == NULL) {		    i++;		    step = &comp->steps[i];		    if (step->op == XML_OP_ROOT)			return(1);		    if (step->op != XML_OP_ELEM)			return(0);		    if (step->value == NULL)			return(-1);		}		if (node == NULL)		    return(0);		if ((node->type == XML_DOCUMENT_NODE) ||		    (node->type == XML_HTML_DOCUMENT_NODE) ||#ifdef LIBXML_DOCB_ENABLED		    (node->type == XML_DOCB_DOCUMENT_NODE) ||#endif		    (node->type == XML_NAMESPACE_DECL))		    return(0);		node = node->parent;		while (node != NULL) {		    if (node == NULL)			return(0);		    if ((node->type == XML_ELEMENT_NODE) &&			(step->value[0] == node->name[0]) &&			(xmlStrEqual(step->value, node->name))) {			/* Namespace test */			if (node->ns == NULL) {			    if (step->value2 == NULL)				break;			} else if (node->ns->href != NULL) {			    if ((step->value2 != NULL) &&			        (xmlStrEqual(step->value2, node->ns->href)))				break;			}		    }		    node = node->parent;		}		if (node == NULL)		    return(0);		continue;            case XML_OP_NS:		if (node->type != XML_ELEMENT_NODE)		    return(0);		if (node->ns == NULL) {		    if (step->value != NULL)			return(0);		} else if (node->ns->href != NULL) {		    if (step->value == NULL)

⌨️ 快捷键说明

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