int xcaps_xpath_get(str *inbuf, str *xpaths, str *outbuf) { xmlDocPtr doc = NULL; xmlXPathContextPtr xpathCtx = NULL; xmlXPathObjectPtr xpathObj = NULL; xmlNodeSetPtr nodes; xmlChar *keyword; xmlBufferPtr psBuf; int size; int i; char *p; char *end; char *pos; doc = xmlParseMemory(inbuf->s, inbuf->len); if(doc == NULL) return -1; xpathCtx = xmlXPathNewContext(doc); if(xpathCtx == NULL) { LM_ERR("unable to create new XPath context\n"); goto error; } /* Evaluate xpath expression */ // xcaps_xpath_register_ns(xpathCtx); xpathObj = xmlXPathEvalExpression( (const xmlChar*)xpaths->s, xpathCtx); if(xpathObj == NULL) { LM_ERR("unable to evaluate xpath expression [%s]\n", xpaths->s); goto error; } nodes = xpathObj->nodesetval; if(nodes==NULL) { outbuf->len = 0; outbuf->s[outbuf->len] = '\0'; goto done; } size = nodes->nodeNr; p = outbuf->s; end = outbuf->s + outbuf->len; for(i = 0; i < size; ++i) { if(nodes->nodeTab[i]==NULL) continue; if(i!=0) { if(p>=end) { LM_ERR("output buffer overflow\n"); goto error; } *p = ','; p++; } if(nodes->nodeTab[i]->type == XML_ATTRIBUTE_NODE) { keyword = xmlNodeListGetString(doc, nodes->nodeTab[i]->children, 0); if(keyword != NULL) { pos = p + strlen((char*)keyword); if(pos>=end) { LM_ERR("output buffer overflow\n"); goto error; } strcpy(p, (char*)keyword); p = pos; xmlFree(keyword); keyword = NULL; } } else { if(nodes->nodeTab[i]->content!=NULL) { pos = p + strlen((char*)nodes->nodeTab[i]->content); if(pos>=end) { LM_ERR("output buffer overflow\n"); goto error; } strcpy(p, (char*)nodes->nodeTab[i]->content); p = pos; } else { psBuf = xmlBufferCreate(); if(psBuf != NULL && xmlNodeDump(psBuf, doc, nodes->nodeTab[i], 0, 0)>0) { pos = p + strlen((char*)xmlBufferContent(psBuf)); if(pos>=end) { LM_ERR("output buffer overflow\n"); goto error; } strcpy(p, (char*)xmlBufferContent(psBuf)); p = pos; } if(psBuf != NULL) xmlBufferFree(psBuf); psBuf = NULL; } } } outbuf->len = p - outbuf->s; outbuf->s[outbuf->len] = '\0'; done: if(xpathObj!=NULL) xmlXPathFreeObject(xpathObj); if(xpathCtx!=NULL) xmlXPathFreeContext(xpathCtx); if(doc!=NULL) xmlFreeDoc(doc); xpathObj = NULL; xpathCtx = NULL; doc = NULL; return 0; error: if(xpathObj!=NULL) xmlXPathFreeObject(xpathObj); if(xpathCtx!=NULL) xmlXPathFreeContext(xpathCtx); if(doc!=NULL) xmlFreeDoc(doc); xpathObj = NULL; xpathCtx = NULL; doc = NULL; outbuf->len = 0; outbuf->s[outbuf->len] = '\0'; return -1; }