Ejemplo n.º 1
0
/**
 * exsltStrConcatFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * Takes a node set and returns the concatenation of the string values
 * of the nodes in that node set.  If the node set is empty, it
 * returns an empty string.
 */
static void
exsltStrConcatFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    xmlXPathObjectPtr obj;
    xmlChar *ret = NULL;
    int i;

    if (nargs  != 1) {
	xmlXPathSetArityError(ctxt);
	return;
    }

    if (!xmlXPathStackIsNodeSet(ctxt)) {
	xmlXPathSetTypeError(ctxt);
	return;
    }

    obj = valuePop (ctxt);

    if (xmlXPathNodeSetIsEmpty(obj->nodesetval)) {
	xmlXPathReturnEmptyString(ctxt);
	return;
    }

    for (i = 0; i < obj->nodesetval->nodeNr; i++) {
	xmlChar *tmp;
	tmp = xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]);

	ret = xmlStrcat (ret, tmp);

	xmlFree(tmp);
    }

    xmlXPathFreeObject (obj);

    xmlXPathReturnString(ctxt, ret);
}
Ejemplo n.º 2
0
static void
xsltp_extension_string_join(xmlXPathParserContextPtr ctxt, int nargs) {
    xmlChar *ret = NULL, *sep = NULL, *str = NULL;
    xmlNodeSetPtr nodeSet = NULL;
    int i, j;

    if (nargs  < 2) {
        xmlXPathSetArityError(ctxt);
        return;
    }

    if (xmlXPathStackIsNodeSet(ctxt)) {
        xmlXPathSetTypeError(ctxt);
        return;
    }

    sep = xmlXPathPopString(ctxt);

    for (i = 1; i < nargs; i++) {
        if (!xmlXPathStackIsNodeSet(ctxt)) {
            str = xmlXPathPopString(ctxt);

            if (i == 1) {
                ret = str;
            }
            else {
                str = xmlStrcat(str, sep);
                str = xmlStrcat(str, ret);
                xmlFree(ret);
                ret = str;
            }
        }
        else {
            nodeSet = xmlXPathPopNodeSet(ctxt);
            if (xmlXPathCheckError(ctxt)) {
                xmlXPathSetTypeError(ctxt);
                goto fail;
            }

            for (j = nodeSet->nodeNr - 1; j >= 0; j--) {
                str = xmlXPathCastNodeToString(nodeSet->nodeTab[j]);

                if (i == 1 && j == (nodeSet->nodeNr - 1)) {
                    ret = str;
                }
                else {
                    str = xmlStrcat(str, sep);
                    str = xmlStrcat(str, ret);
                    xmlFree(ret);
                    ret = str;
                }
            }

            xmlXPathFreeNodeSet(nodeSet);
        }
    }

    xmlXPathReturnString(ctxt, ret);

fail:
    if (sep != NULL)
        xmlFree(sep);
}
Ejemplo n.º 3
0
static void
exsltDynMapFunction(xmlXPathParserContextPtr ctxt, int nargs)
{
    xmlChar *str = NULL;
    xmlNodeSetPtr nodeset = NULL;
    xsltTransformContextPtr tctxt;
    xmlXPathCompExprPtr comp = NULL;
    xmlXPathObjectPtr ret = NULL;
    xmlDocPtr oldDoc, container = NULL;
    xmlNodePtr oldNode;
    int oldContextSize;
    int oldProximityPosition;
    int i, j;


    if (nargs != 2) {
        xmlXPathSetArityError(ctxt);
        return;
    }
    str = xmlXPathPopString(ctxt);
    if (xmlXPathCheckError(ctxt)) {
        xmlXPathSetTypeError(ctxt);
        return;
    }

    nodeset = xmlXPathPopNodeSet(ctxt);
    if (xmlXPathCheckError(ctxt)) {
        xmlXPathSetTypeError(ctxt);
        return;
    }
    if (str == NULL || !xmlStrlen(str) || !(comp = xmlXPathCompile(str))) {
        if (nodeset != NULL)
            xmlXPathFreeNodeSet(nodeset);
        if (str != NULL)
            xmlFree(str);
        valuePush(ctxt, xmlXPathNewNodeSet(NULL));
        return;
    }

    ret = xmlXPathNewNodeSet(NULL);
    if (ret == NULL) {
        xsltGenericError(xsltGenericErrorContext,
                         "exsltDynMapFunction: ret == NULL\n");
        goto cleanup;
    }

    oldDoc = ctxt->context->doc;
    oldNode = ctxt->context->node;
    oldContextSize = ctxt->context->contextSize;
    oldProximityPosition = ctxt->context->proximityPosition;

    tctxt = xsltXPathGetTransformContext(ctxt);
    if (tctxt == NULL) {
	xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
	      "dyn:map : internal error tctxt == NULL\n");
	goto cleanup;
    }
    container = xsltCreateRVT(tctxt);
    if (container == NULL) {
	xsltTransformError(tctxt, NULL, NULL,
	      "dyn:map : internal error container == NULL\n");
	goto cleanup;
    }
    xsltRegisterLocalRVT(tctxt, container);
    if (nodeset && nodeset->nodeNr > 0) {
        xmlXPathNodeSetSort(nodeset);
        ctxt->context->contextSize = nodeset->nodeNr;
        ctxt->context->proximityPosition = 0;
        for (i = 0; i < nodeset->nodeNr; i++) {
            xmlXPathObjectPtr subResult = NULL;

            ctxt->context->proximityPosition++;
            ctxt->context->node = nodeset->nodeTab[i];
            ctxt->context->doc = nodeset->nodeTab[i]->doc;

            subResult = xmlXPathCompiledEval(comp, ctxt->context);
            if (subResult != NULL) {
                switch (subResult->type) {
                    case XPATH_NODESET:
                        if (subResult->nodesetval != NULL)
                            for (j = 0; j < subResult->nodesetval->nodeNr;
                                 j++)
                                xmlXPathNodeSetAdd(ret->nodesetval,
                                                   subResult->nodesetval->
                                                   nodeTab[j]);
                        break;
                    case XPATH_BOOLEAN:
                        if (container != NULL) {
                            xmlNodePtr cur =
                                xmlNewChild((xmlNodePtr) container, NULL,
                                            BAD_CAST "boolean",
                                            BAD_CAST (subResult->
                                            boolval ? "true" : ""));
                            if (cur != NULL) {
                                cur->ns =
                                    xmlNewNs(cur,
                                             BAD_CAST
                                             "http://exslt.org/common",
                                             BAD_CAST "exsl");
                                xmlXPathNodeSetAddUnique(ret->nodesetval,
                                                         cur);
                            }
			    xsltExtensionInstructionResultRegister(tctxt, ret);
                        }
                        break;
                    case XPATH_NUMBER:
                        if (container != NULL) {
                            xmlChar *val =
                                xmlXPathCastNumberToString(subResult->
                                                           floatval);
                            xmlNodePtr cur =
                                xmlNewChild((xmlNodePtr) container, NULL,
                                            BAD_CAST "number", val);
                            if (val != NULL)
                                xmlFree(val);

                            if (cur != NULL) {
                                cur->ns =
                                    xmlNewNs(cur,
                                             BAD_CAST
                                             "http://exslt.org/common",
                                             BAD_CAST "exsl");
                                xmlXPathNodeSetAddUnique(ret->nodesetval,
                                                         cur);
                            }
			    xsltExtensionInstructionResultRegister(tctxt, ret);
                        }
                        break;
                    case XPATH_STRING:
                        if (container != NULL) {
                            xmlNodePtr cur =
                                xmlNewChild((xmlNodePtr) container, NULL,
                                            BAD_CAST "string",
                                            subResult->stringval);
                            if (cur != NULL) {
                                cur->ns =
                                    xmlNewNs(cur,
                                             BAD_CAST
                                             "http://exslt.org/common",
                                             BAD_CAST "exsl");
                                xmlXPathNodeSetAddUnique(ret->nodesetval,
                                                         cur);
                            }
			    xsltExtensionInstructionResultRegister(tctxt, ret);
                        }
                        break;
		    default:
                        break;
                }
                xmlXPathFreeObject(subResult);
            }
        }
    }
    ctxt->context->doc = oldDoc;
    ctxt->context->node = oldNode;
    ctxt->context->contextSize = oldContextSize;
    ctxt->context->proximityPosition = oldProximityPosition;


  cleanup:
    
    if (comp != NULL)
        xmlXPathFreeCompExpr(comp);
    if (nodeset != NULL)
        xmlXPathFreeNodeSet(nodeset);
    if (str != NULL)
        xmlFree(str);
    valuePush(ctxt, ret);
    return;
}
Ejemplo n.º 4
0
/**
 * exsltStrReplaceFunction:
 * @ctxt: an XPath parser context
 * @nargs: the number of arguments
 *
 * Takes a string, and two node sets and returns the string with all strings in
 * the first node set replaced by all strings in the second node set.
 */
static void
exsltStrReplaceFunction (xmlXPathParserContextPtr ctxt, int nargs) {
    xmlChar *str = NULL, *searchStr = NULL, *replaceStr = NULL;
    xmlNodeSetPtr replaceSet = NULL, searchSet = NULL;
    xmlChar *ret = NULL, *retSwap = NULL;
    int i;

    if (nargs  != 3) {
        xmlXPathSetArityError(ctxt);
        return;
    }

    /* pull out replace argument */
    if (!xmlXPathStackIsNodeSet(ctxt)) {
        replaceStr = xmlXPathPopString(ctxt);
    }
    else {
        replaceSet = xmlXPathPopNodeSet(ctxt);
        if (xmlXPathCheckError(ctxt)) {
            xmlXPathSetTypeError(ctxt);
            goto fail;
        }
    }

    /* behavior driven by search argument from here on */
    if (!xmlXPathStackIsNodeSet(ctxt)) {
        searchStr = xmlXPathPopString(ctxt);
        str = xmlXPathPopString(ctxt);

        if (replaceStr == NULL) {
            xmlXPathSetTypeError(ctxt);
            goto fail;
        }

        ret = exsltStrReplaceInternal(str, searchStr, replaceStr);
    }
    else {
        searchSet = xmlXPathPopNodeSet(ctxt);
        if (searchSet == NULL || xmlXPathCheckError(ctxt)) {
            xmlXPathSetTypeError(ctxt);
            goto fail;
        }

        str = xmlXPathPopString(ctxt);
        ret = xmlStrdup(str);

        for (i = 0; i < searchSet->nodeNr; i++) {
            searchStr = xmlXPathCastNodeToString(searchSet->nodeTab[i]);

            if (replaceSet != NULL) {
                replaceStr = NULL;
                if (i < replaceSet->nodeNr) {
                    replaceStr = xmlXPathCastNodeToString(replaceSet->nodeTab[i]);
                }

                retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr);

                if (replaceStr != NULL) {
                    xmlFree(replaceStr);
                    replaceStr = NULL;
                }
            }
            else {
                retSwap = exsltStrReplaceInternal(ret, searchStr, replaceStr);
            }

            xmlFree(ret);
            if (searchStr != NULL) {
                xmlFree(searchStr);
                searchStr = NULL;
            }

            ret = retSwap;
        }

        if (replaceSet != NULL)
            xmlXPathFreeNodeSet(replaceSet);

        if (searchSet != NULL)
            xmlXPathFreeNodeSet(searchSet);
    }

    xmlXPathReturnString(ctxt, ret);

fail:
    if (replaceStr != NULL)
        xmlFree(replaceStr);

    if (searchStr != NULL)
        xmlFree(searchStr);

    if (str != NULL)
        xmlFree(str);
}