示例#1
0
文件: functions.c 项目: Paxxi/libxslt
/**
 * xsltUnparsedEntityURIFunction:
 * @ctxt:  the XPath Parser context
 * @nargs:  the number of arguments
 *
 * Implement the unparsed-entity-uri() XSLT function
 *   string unparsed-entity-uri(string)
 */
void
xsltUnparsedEntityURIFunction(xmlXPathParserContextPtr ctxt, int nargs){
    xmlXPathObjectPtr obj;
    xmlChar *str;

    if ((nargs != 1) || (ctxt->value == NULL)) {
        xsltGenericError(xsltGenericErrorContext,
		"unparsed-entity-uri() : expects one string arg\n");
	ctxt->error = XPATH_INVALID_ARITY;
	return;
    }
    obj = valuePop(ctxt);
    if (obj->type != XPATH_STRING) {
	obj = xmlXPathConvertString(obj);
    }

    str = obj->stringval;
    if (str == NULL) {
	valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
    } else {
	xmlEntityPtr entity;

	entity = xmlGetDocEntity(ctxt->context->doc, str);
	if (entity == NULL) {
	    valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
	} else {
	    if (entity->URI != NULL)
		valuePush(ctxt, xmlXPathNewString(entity->URI));
	    else
		valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
	}
    }
    xmlXPathFreeObject(obj);
}
示例#2
0
/**
 * xsltEvalXPathStringNs:
 * @ctxt:  the XSLT transformation context
 * @comp:  the compiled XPath expression
 * @nsNr:  the number of namespaces in the list
 * @nsList:  the list of in-scope namespaces to use
 *
 * Process the expression using XPath, allowing to pass a namespace mapping
 * context and get a string
 *
 * Returns the computed string value or NULL, must be deallocated by the
 *    caller.
 */
xmlChar *
xsltEvalXPathStringNs(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp,
	              int nsNr, xmlNsPtr *nsList) {
    xmlChar *ret = NULL;
    xmlXPathObjectPtr res;
    xmlNodePtr oldInst;
    xmlNodePtr oldNode;
    int	oldPos, oldSize;
    int oldNsNr;
    xmlNsPtr *oldNamespaces;

    oldInst = ctxt->inst;
    oldNode = ctxt->node;
    oldPos = ctxt->xpathCtxt->proximityPosition;
    oldSize = ctxt->xpathCtxt->contextSize;
    oldNsNr = ctxt->xpathCtxt->nsNr;
    oldNamespaces = ctxt->xpathCtxt->namespaces;

    ctxt->xpathCtxt->node = ctxt->node;
    /* TODO: do we need to propagate the namespaces here ? */
    ctxt->xpathCtxt->namespaces = nsList;
    ctxt->xpathCtxt->nsNr = nsNr;
    res = xmlXPathCompiledEval(comp, ctxt->xpathCtxt);
    if (res != NULL) {
	if (res->type != XPATH_STRING)
	    res = xmlXPathConvertString(res);
	if (res->type == XPATH_STRING) {
            ret = res->stringval;
	    res->stringval = NULL;
	} else {
	    xsltTransformError(ctxt, NULL, NULL,
		 "xpath : string() function didn't return a String\n");
	}
	xmlXPathFreeObject(res);
    } else {
	ctxt->state = XSLT_STATE_STOPPED;
    }
#ifdef WITH_XSLT_DEBUG_TEMPLATES
    XSLT_TRACE(ctxt,XSLT_TRACE_TEMPLATES,xsltGenericDebug(xsltGenericDebugContext,
	 "xsltEvalXPathString: returns %s\n", ret));
#endif
    ctxt->inst = oldInst;
    ctxt->node = oldNode;
    ctxt->xpathCtxt->contextSize = oldSize;
    ctxt->xpathCtxt->proximityPosition = oldPos;
    ctxt->xpathCtxt->nsNr = oldNsNr;
    ctxt->xpathCtxt->namespaces = oldNamespaces;
    return(ret);
}
示例#3
0
char *
compGetStringFromMetadataPath (CompMetadata *metadata,
			       const char   *path)
{
    CompXPath xPath;
    char      *v = NULL;

    if (!initXPathFromMetadataPath (&xPath, metadata, BAD_CAST path))
	return NULL;

    xPath.obj = xmlXPathConvertString (xPath.obj);

    if (xPath.obj->type == XPATH_STRING && xPath.obj->stringval)
	v = strdup ((char *) xPath.obj->stringval);

    finiXPath (&xPath);

    return v;
}
示例#4
0
/**
 * xsltFunctionLocalTime:
 * @ctxt:  the XPath Parser context
 * @nargs:  the number of arguments
 *
 * Implement the localTime XSLT function used by NORM
 *   string localTime(???)
 *
 * This function is available in Norm's extension namespace
 * Code (and comments) contributed by Norm
 */
static void
xsltFunctionLocalTime(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr obj;
    char *str;
    char digits[5];
    char result[29];
    long int field;
    time_t gmt, lmt;
    struct tm gmt_tm;
    struct tm *local_tm;
 
    if (nargs != 1) {
       xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
                      "localTime() : invalid number of args %d\n", nargs);
       ctxt->error = XPATH_INVALID_ARITY;
       return;
    }
 
    obj = valuePop(ctxt);

    if (obj->type != XPATH_STRING) {
	obj = xmlXPathConvertString(obj);
    }
    if (obj == NULL) {
	valuePush(ctxt, xmlXPathNewString((const xmlChar *)""));
	return;
    }
    
    str = (char *) obj->stringval;

    /* str = "$Date: Tuesday, November 03, 2009 11:37:25 AM$" */
    memset(digits, 0, sizeof(digits));
    strncpy(digits, str+7, 4);
    field = strtol(digits, NULL, 10);
    gmt_tm.tm_year = field - 1900;

    memset(digits, 0, sizeof(digits));
    strncpy(digits, str+12, 2);
    field = strtol(digits, NULL, 10);
    gmt_tm.tm_mon = field - 1;

    memset(digits, 0, sizeof(digits));
    strncpy(digits, str+15, 2);
    field = strtol(digits, NULL, 10);
    gmt_tm.tm_mday = field;

    memset(digits, 0, sizeof(digits));
    strncpy(digits, str+18, 2);
    field = strtol(digits, NULL, 10);
    gmt_tm.tm_hour = field;

    memset(digits, 0, sizeof(digits));
    strncpy(digits, str+21, 2);
    field = strtol(digits, NULL, 10);
    gmt_tm.tm_min = field;

    memset(digits, 0, sizeof(digits));
    strncpy(digits, str+24, 2);
    field = strtol(digits, NULL, 10);
    gmt_tm.tm_sec = field;

    /* Now turn gmt_tm into a time. */
    gmt = mktime(&gmt_tm);


    /*
     * FIXME: it's been too long since I did manual memory management.
     * (I swore never to do it again.) Does this introduce a memory leak?
     */
    local_tm = localtime(&gmt);

    /*
     * Calling localtime() has the side-effect of setting timezone.
     * After we know the timezone, we can adjust for it
     */
    lmt = gmt - timezone;

    /*
     * FIXME: it's been too long since I did manual memory management.
     * (I swore never to do it again.) Does this introduce a memory leak?
     */
    local_tm = localtime(&lmt);

    /*
     * Now convert local_tm back into a string. This doesn't introduce
     * a memory leak, so says asctime(3).
     */

    str = asctime(local_tm);           /* "Tue Jun 26 05:02:16 2001" */
                                       /*  0123456789 123456789 123 */

    memset(result, 0, sizeof(result)); /* "Thu, 26 Jun 2001" */
                                       /*  0123456789 12345 */

    strncpy(result, str, 20);
    strcpy(result+20, "???");          /* tzname doesn't work, fake it */
    strncpy(result+23, str+19, 5);

    /* Ok, now result contains the string I want to send back. */
    valuePush(ctxt, xmlXPathNewString((xmlChar *)result));
}
示例#5
0
/**
 *  'update' operation
 */
static void
edUpdate(xmlDocPtr doc, xmlNodeSetPtr nodes, const char *val,
    XmlNodeType type, xmlXPathContextPtr ctxt)
{
    int i;
    xmlXPathCompExprPtr xpath = NULL;

    if (type == XML_EXPR) {
        xpath = xmlXPathCompile((const xmlChar*) val);
        if (!xpath) return;
    }

    for (i = 0; i < nodes->nodeNr; i++)
    {
        /* update node */
        if (type == XML_EXPR) {
            xmlXPathObjectPtr res;

            ctxt->node = nodes->nodeTab[i];
            res = xmlXPathCompiledEval(xpath, ctxt);
            if (res->type == XPATH_NODESET || res->type == XPATH_XSLT_TREE) {
                int j;
                xmlNodePtr oldChild;
                xmlNodeSetPtr oldChildren = xmlXPathNodeSetCreate(NULL);
                /* NOTE: newChildren can be NULL for empty result set */
                xmlNodeSetPtr newChildren = res->nodesetval;

                /* NOTE: nodes can be both oldChildren and newChildren */

                /* unlink the old children */
                for (oldChild = nodes->nodeTab[i]->children; oldChild; oldChild = oldChild->next) {
                    xmlUnlinkNode(oldChild);
                    /* we can't free it now because an oldChild can also be
                       newChild! just put it in the list */
                    xmlXPathNodeSetAdd(oldChildren, oldChild);
                }

                /* add the new children */
                for (j = 0; newChildren && j < newChildren->nodeNr; j++) {
                    xmlNodePtr node = newChildren->nodeTab[j];
                    xmlAddChild(nodes->nodeTab[i],
                        /* if node is linked to this doc we need to copy */
                        (node->doc == doc)? xmlDocCopyNode(node, doc, 1) : node);
                    newChildren->nodeTab[j] = NULL;
                }
                newChildren->nodeNr = 0;

                /* NOTE: if any oldChildren were newChildren, they've been
                   copied so we can free them all now */
                for (j = 0; j < oldChildren->nodeNr; j++) {
                    xmlFreeNode(oldChildren->nodeTab[j]);
                    oldChildren->nodeTab[j] = NULL;
                }
                oldChildren->nodeNr = 0;
                xmlXPathFreeNodeSet(oldChildren);
            } else {
                res = xmlXPathConvertString(res);
                update_string(doc, nodes->nodeTab[i], res->stringval);
            }
            xmlXPathFreeObject(res);
        } else {
            update_string(doc, nodes->nodeTab[i], (const xmlChar*) val);
        }
    }

    xmlXPathFreeCompExpr(xpath);
}
示例#6
0
static int
printXPathObject(xmlXPathObjectPtr item, xmlChar* xPath){
  int result = 0;
  if (item){ 
    switch (item->type) {
    case XPATH_BOOLEAN:
      xsltGenericError(xsltGenericErrorContext,
		       "= %s\n%s\n", xPath,
		       xmlBoolToText(item->boolval));
      result = 1;
      break;

    case XPATH_NUMBER:
      xsltGenericError(xsltGenericErrorContext,
		       "= %s\n%0g\n", xPath, item->floatval);
      result = 1;
      break;

      /*  case XPATH_NODESET:*/
    default:{
	/* We may need to convert this XPath to a string,
	   plus ensure that we print required the number of
	   lines of text */
	int indx;

	const char *fileName = filesTempFileName(0);
	FILE *file = NULL;

	if (!fileName)
	  break;
	file = fopen(fileName, "w+");
	if (!file) {
	   xsldbgGenericErrorFunc(i18n("Error: Unable to save temporary results to %1.\n").arg(xsldbgText(fileName)));
	  break;
	} else {
	  fprintf(file, "= %s\n", xPath);
	  switch(item->type){

	  case XPATH_NODESET:
	    if (item->nodesetval){
	      for (indx = 0;
		   indx < item->nodesetval->nodeNr; indx++){ 
				xslDbgCatToFile(item->nodesetval->
						nodeTab[indx], file);
	      }
	    } else {
	      xsldbgGenericErrorFunc(i18n("Error: XPath %1 results in an empty Node Set.\n").arg(xsldbgText(xPath)));
	    }
	    break;
			     
	  case XPATH_STRING:
	    if (item->stringval)
	      fprintf(file, "\'%s\'", item->stringval);
	    else
	      fprintf(file, "%s", i18n("NULL string value supplied.").utf8().data());
	    break;
			     
	  default:{
	      xmlXPathObjectPtr tempObj = 
		xmlXPathObjectCopy(item);
	      if (tempObj)
		tempObj = xmlXPathConvertString(tempObj);
	      if (tempObj && tempObj->stringval){
		fprintf(file, "%s", tempObj->stringval);
	      }else{
		fprintf(file, "%s", i18n("Unable to convert XPath to string.").utf8().data());	
	      }
	      if (tempObj)
		xmlXPathFreeObject(tempObj);
	    }
	    break;
	    fprintf(file,"\n");	    

	  } /* inner switch statement  */
	  if (getThreadStatus() == XSLDBG_MSG_THREAD_RUN) {
	    fclose(file);
	    file = NULL;
	    /* send the data to application */
	    notifyXsldbgApp(XSLDBG_MSG_FILEOUT, fileName);
	  } else {
	    int lineCount = 0, gdbModeEnabled = 0;

	    /* save the value of option to speed things up
	     * a bit */
	    gdbModeEnabled =
	      optionsGetIntOption(OPTIONS_GDB);
	    rewind(file);

	    /* when gdb mode is enable then only print the first
	     * GDB_LINES_TO_PRINT lines */
	    while (!feof(file)) {
	      if (fgets
		  ((char *) nodeViewBuffer, sizeof(nodeViewBuffer),
		   file))
		xsltGenericError
		  (xsltGenericErrorContext, "%s",
		   nodeViewBuffer);
	      if (gdbModeEnabled) {
		lineCount++;
		/* there is an overhead of two lines
		 * when print expression values */
		if (lineCount ==
		    GDB_LINES_TO_PRINT + 2) {
		  xsltGenericError
		    (xsltGenericErrorContext,
		     "...");
		  break;
		}
	      }
	    }
	    xsltGenericError
	      (xsltGenericErrorContext, "\n");
	  }
	  if (file)
	    fclose(file);
	  result = 1;
	  break;
	}
      }
    }
  }
  return result;
}