char* xode_get_data(xode node) { xode cur; if(node == NULL) return NULL; if(xode_get_type(node) == XODE_TYPE_TAG) /* loop till we find a CDATA */ { for(cur = xode_get_firstchild(node); cur != NULL; cur = xode_get_nextsibling(cur)) if(xode_get_type(cur) == XODE_TYPE_CDATA) return cur->data; }else{ return node->data; } return NULL; }
/* loop through both a and b comparing everything, attribs, cdata, children, etc */ int xode_cmp(xode a, xode b) { int ret = 0; while(1) { if(a == NULL && b == NULL) return 0; if(a == NULL || b == NULL) return -1; if(xode_get_type(a) != xode_get_type(b)) return -1; switch(xode_get_type(a)) { case XODE_TYPE_ATTRIB: ret = _xode_strcmp(xode_get_name(a), xode_get_name(b)); if(ret != 0) return -1; ret = _xode_strcmp(xode_get_data(a), xode_get_data(b)); if(ret != 0) return -1; break; case XODE_TYPE_TAG: ret = _xode_strcmp(xode_get_name(a), xode_get_name(b)); if(ret != 0) return -1; ret = xode_cmp(xode_get_firstattrib(a), xode_get_firstattrib(b)); if(ret != 0) return -1; ret = xode_cmp(xode_get_firstchild(a), xode_get_firstchild(b)); if(ret != 0) return -1; break; case XODE_TYPE_CDATA: ret = _xode_strcmp(xode_get_data(a), xode_get_data(b)); if(ret != 0) return -1; } a = xode_get_nextsibling(a); b = xode_get_nextsibling(b); } }
int xode_get_datasz(xode node) { if( node == NULL ) { return (int)(long)NULL; } else if(xode_get_type(node) == XODE_TYPE_TAG) /* loop till we find a CDATA */ { xode cur; for(cur = xode_get_firstchild(node); cur != NULL; cur = xode_get_nextsibling(cur)) if(xode_get_type(cur) == XODE_TYPE_CDATA) return cur->data_sz; }else{ return node->data_sz; } return (int)(long)NULL; }
void _xode_to_prettystr( xode_spool s, xode x, int deep ) { int i; xode y; if(xode_get_type(x) != XODE_TYPE_TAG) return; for(i=0; i<deep; i++) xode_spool_add(s, "\t"); xode_spooler( s , "<" , xode_get_name(x) , s ); y = xode_get_firstattrib(x); while( y ) { xode_spooler( s , " " , xode_get_name(y) , "='", xode_get_data(y) , "'" , s ); y = xode_get_nextsibling( y ); } xode_spool_add(s,">"); xode_spool_add(s,"\n"); if( xode_get_data(x)) { for(i=0; i<=deep; i++) xode_spool_add(s, "\t"); xode_spool_add( s , xode_get_data(x)); } y = xode_get_firstchild(x); while( y ) { _xode_to_prettystr(s , y, deep+1); y = xode_get_nextsibling(y); xode_spool_add(s,"\n"); } for(i=0; i<deep; i++) xode_spool_add(s, "\t"); xode_spooler( s , "</" , xode_get_name(x) , ">" , s ); return; }
/* places copy of node and node's siblings in parent */ void xode_insert_node(xode parent, xode node) { if(node == NULL || parent == NULL) return; while(node != NULL) { switch(xode_get_type(node)) { case XODE_TYPE_ATTRIB: xode_put_attrib(parent, xode_get_name(node), xode_get_data(node)); break; case XODE_TYPE_TAG: xode_insert_tagnode(parent, node); break; case XODE_TYPE_CDATA: xode_insert_cdata(parent, xode_get_data(node), xode_get_datasz(node)); } node = xode_get_nextsibling(node); } }
/* * xode_gettag -- find given tag in an xode tree * * parameters * parent -- pointer to the parent tag * name -- "name" for the child tag of that name * "name/name" for a sub child (recurses) * "?attrib" to match the first tag with that attrib defined * "?attrib=value" to match the first tag with that attrib and value * or any combination: "name/name/?attrib", etc * * results * a pointer to the tag matching search criteria * or NULL if search was unsuccessful */ xode xode_get_tag(xode parent, const char* name) { char *str, *slash, *qmark, *equals; xode step, ret; if(parent == NULL || parent->firstchild == NULL || name == NULL || name == '\0') return NULL; if(strstr(name, "/") == NULL && strstr(name,"?") == NULL) return _xode_search(parent->firstchild, name, XODE_TYPE_TAG); /* jer's note: why can't I modify the name directly, why do I have to strdup it? damn c grrr! */ str = strdup(name); slash = strstr(str, "/"); qmark = strstr(str, "?"); equals = strstr(str, "="); if(qmark != NULL && (slash == NULL || qmark < slash)) { /* of type ?attrib */ *qmark = '\0'; qmark++; if(equals != NULL) { *equals = '\0'; equals++; } for(step = parent->firstchild; step != NULL; step = xode_get_nextsibling(step)) { if(xode_get_type(step) != XODE_TYPE_TAG) continue; if(*str != '\0') if(_xode_strcmp(xode_get_name(step),str) != 0) continue; if(xode_get_attrib(step,qmark) == NULL) continue; if(equals != NULL && _xode_strcmp(xode_get_attrib(step,qmark),equals) != 0) continue; break; } free(str); return step; } *slash = '\0'; ++slash; for(step = parent->firstchild; step != NULL; step = xode_get_nextsibling(step)) { if(xode_get_type(step) != XODE_TYPE_TAG) continue; if(_xode_strcmp(xode_get_name(step),str) != 0) continue; ret = xode_get_tag(step, slash); if(ret != NULL) { free(str); return ret; } } free(str); return NULL; }