static int xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context, xmlNodePtr node, xsltCompMatchPtr countPat, xsltCompMatchPtr fromPat, double *array, int max) { int amount = 0; int cnt; xmlNodePtr ancestor; xmlNodePtr preceding; xmlXPathParserContextPtr parser; context->xpathCtxt->node = node; parser = xmlXPathNewParserContext(NULL, context->xpathCtxt); if (parser) { /* ancestor-or-self::*[count] */ for (ancestor = node; (ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE); ancestor = xmlXPathNextAncestor(parser, ancestor)) { if ((fromPat != NULL) && xsltTestCompMatchList(context, ancestor, fromPat)) break; /* for */ if (xsltTestCompMatchCount(context, ancestor, countPat, node)) { /* count(preceding-sibling::*) */ cnt = 1; for (preceding = xmlXPathNextPrecedingSibling(parser, ancestor); preceding != NULL; preceding = xmlXPathNextPrecedingSibling(parser, preceding)) { if (xsltTestCompMatchCount(context, preceding, countPat, node)) cnt++; } array[amount++] = (double)cnt; if (amount >= max) break; /* for */ } } xmlXPathFreeParserContext(parser); } return amount; }
/** * @arg str the XPath expression * @arg ctxt the XPath context * @arg pctxt pointer to a XPath Parser context pointer * * Evaluate the XPath expression in the given context. The XPath Parser * context is saved in pctxt, so that it can be accessed from another thread. * Especially the error state is interesting, since it can be used to stop a * never ending evaluation. * * Taken from xpath.c in libxml2-2.6.16. * * @return the xmlXPathObjectPtr resulting from the evaluation or NULL. * The caller has to free the object. */ xmlXPathObjectPtr my_xmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt, xmlXPathParserContextPtr *pctxt) { xmlXPathObjectPtr res, tmp; int stack = 0; xmlXPathInit(); // it is nice that gcc gives no warning anymore, // but the bad thing is that *pctxt normally is still NULL at this point CHECK_CONTEXT(ctxt,*pctxt) g_mutex_lock(find_nodeset_pcontext_mutex); //g_printerr("Allocating parser context\n"); *pctxt = xmlXPathNewParserContext(str, ctxt); g_mutex_unlock(find_nodeset_pcontext_mutex); xmlXPathEvalExpr(*pctxt); if (*(*pctxt)->cur != 0) { xmlXPatherror(*pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR); res = NULL; } else { res = valuePop(*pctxt); } do { tmp = valuePop(*pctxt); if (tmp != NULL) { xmlXPathFreeObject(tmp); stack++; } } while (tmp != NULL); if ((stack != 0) && (res != NULL)) { xmlGenericError(xmlGenericErrorContext, "xmlXPathEvalExpression: %d object left on the stack\n", stack); } g_mutex_lock(find_nodeset_pcontext_mutex); xmlXPathFreeParserContext(*pctxt); *pctxt = NULL; //g_printerr("Freed parser context\n"); g_mutex_unlock(find_nodeset_pcontext_mutex); return(res); }
static int xsltNumberFormatGetMultipleLevel(xsltTransformContextPtr context, xmlNodePtr node, xmlChar *count, xmlChar *from, double *array, int max, xmlDocPtr doc, xmlNodePtr elem) { int amount = 0; int cnt; xmlNodePtr ancestor; xmlNodePtr preceding; xmlXPathParserContextPtr parser; xsltCompMatchPtr countPat; xsltCompMatchPtr fromPat; if (count != NULL) countPat = xsltCompilePattern(count, doc, elem, NULL, context); else countPat = NULL; if (from != NULL) fromPat = xsltCompilePattern(from, doc, elem, NULL, context); else fromPat = NULL; context->xpathCtxt->node = node; parser = xmlXPathNewParserContext(NULL, context->xpathCtxt); if (parser) { /* ancestor-or-self::*[count] */ for (ancestor = node; (ancestor != NULL) && (ancestor->type != XML_DOCUMENT_NODE); ancestor = xmlXPathNextAncestor(parser, ancestor)) { if ((from != NULL) && xsltTestCompMatchList(context, ancestor, fromPat)) break; /* for */ if ((count == NULL) || xsltTestCompMatchList(context, ancestor, countPat)) { /* count(preceding-sibling::*) */ cnt = 0; for (preceding = ancestor; preceding != NULL; preceding = xmlXPathNextPrecedingSibling(parser, preceding)) { if (count == NULL) { if ((preceding->type == ancestor->type) && /* FIXME */ xmlStrEqual(preceding->name, ancestor->name)) cnt++; } else { if (xsltTestCompMatchList(context, preceding, countPat)) cnt++; } } array[amount++] = (double)cnt; if (amount >= max) break; /* for */ } } xmlXPathFreeParserContext(parser); } xsltFreeCompMatchList(countPat); xsltFreeCompMatchList(fromPat); return amount; }