/** * xsltGenerateIdFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the generate-id() XSLT function * string generate-id(node-set?) */ void xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ static char base_address; xmlNodePtr cur = NULL; xmlXPathObjectPtr obj = NULL; long val; xmlChar str[30]; if (nargs == 0) { cur = ctxt->context->node; } else if (nargs == 1) { xmlNodeSetPtr nodelist; int i, ret; if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) { ctxt->error = XPATH_INVALID_TYPE; xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "generate-id() : invalid arg expecting a node-set\n"); return; } obj = valuePop(ctxt); nodelist = obj->nodesetval; if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) { xmlXPathFreeObject(obj); valuePush(ctxt, xmlXPathNewCString("")); return; } cur = nodelist->nodeTab[0]; for (i = 1;i < nodelist->nodeNr;i++) { ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]); if (ret == -1) cur = nodelist->nodeTab[i]; } } else { xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, "generate-id() : invalid number of args %d\n", nargs); ctxt->error = XPATH_INVALID_ARITY; return; } if (obj) xmlXPathFreeObject(obj); val = (long)((char *)cur - (char *)&base_address); if (val >= 0) { snprintf((char *)str, sizeof(str), "idp%ld", val); } else { snprintf((char *)str, sizeof(str), "idm%ld", -val); } valuePush(ctxt, xmlXPathNewString(str)); }
/** * xsltGenerateIdFunction: * @ctxt: the XPath Parser context * @nargs: the number of arguments * * Implement the generate-id() XSLT function * string generate-id(node-set?) */ void xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ xmlNodePtr cur = NULL; unsigned long val; xmlChar str[20]; if (nargs == 0) { cur = ctxt->context->node; } else if (nargs == 1) { xmlXPathObjectPtr obj; xmlNodeSetPtr nodelist; int i, ret; if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) { ctxt->error = XPATH_INVALID_TYPE; xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "generate-id() : invalid arg expecting a node-set\n"); return; } obj = valuePop(ctxt); nodelist = obj->nodesetval; if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) { xmlXPathFreeObject(obj); valuePush(ctxt, xmlXPathNewCString("")); return; } cur = nodelist->nodeTab[0]; for (i = 1;i < nodelist->nodeNr;i++) { ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]); if (ret == -1) cur = nodelist->nodeTab[i]; } xmlXPathFreeObject(obj); } else { xsltPrintErrorContext(xsltXPathGetTransformContext(ctxt), NULL, NULL); xsltGenericError(xsltGenericErrorContext, "generate-id() : invalid number of args %d\n", nargs); ctxt->error = XPATH_INVALID_ARITY; return; } /* * Okay this is ugly but should work, use the NodePtr address * to forge the ID */ val = (unsigned long)((char *)cur - (char *)0); val /= sizeof(xmlNode); sprintf((char *)str, "id%ld", val); valuePush(ctxt, xmlXPathNewString(str)); }
/* * call-seq: * register_variable(name, value) * * Register the variable +name+ with +value+. */ static VALUE register_variable(VALUE self, VALUE name, VALUE value) { xmlXPathContextPtr ctx; xmlXPathObjectPtr xmlValue; Data_Get_Struct(self, xmlXPathContext, ctx); xmlValue = xmlXPathNewCString(StringValuePtr(value)); xmlXPathRegisterVariable( ctx, (const xmlChar *)StringValuePtr(name), xmlValue ); return self; }
static void exsltObjectTypeFunction (xmlXPathParserContextPtr ctxt, int nargs) { xmlXPathObjectPtr obj, ret; if (nargs != 1) { xmlXPathSetArityError(ctxt); return; } obj = valuePop(ctxt); switch (obj->type) { case XPATH_STRING: ret = xmlXPathNewCString("string"); break; case XPATH_NUMBER: ret = xmlXPathNewCString("number"); break; case XPATH_BOOLEAN: ret = xmlXPathNewCString("boolean"); break; case XPATH_NODESET: ret = xmlXPathNewCString("node-set"); break; case XPATH_XSLT_TREE: ret = xmlXPathNewCString("RTF"); break; case XPATH_USERS: ret = xmlXPathNewCString("external"); break; default: xsltGenericError(xsltGenericErrorContext, "object-type() invalid arg\n"); ctxt->error = XPATH_INVALID_TYPE; xmlXPathFreeObject(obj); return; } xmlXPathFreeObject(obj); valuePush(ctxt, ret); }