#define IN_LIBEXSLT #include "libexslt/libexslt.h" #if defined(WIN32) && !defined (__CYGWIN__) && (!__MINGW32__) #include <win32config.h> #else #include "config.h" #endif #include <libxml/tree.h> #include <libxml/xpath.h> #include <libxml/xpathInternals.h> #include <libxslt/xsltconfig.h> #include <libxslt/xsltutils.h> #include <libxslt/xsltInternals.h> #include <libxslt/extensions.h> #include <libxslt/transform.h> #include <libxslt/extra.h> #include <libxslt/preproc.h> #include "exslt.h" static void exsltNodeSetFunction (xmlXPathParserContextPtr ctxt, int nargs) { if (nargs != 1) { xmlXPathSetArityError(ctxt); return; } if (xmlXPathStackIsNodeSet (ctxt)) { xsltFunctionNodeSet (ctxt, nargs); return; } else { xmlDocPtr fragment; xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt); xmlNodePtr txt; xmlChar *strval; xmlXPathObjectPtr obj; /* * SPEC EXSLT: * "You can also use this function to turn a string into a text * node, which is helpful if you want to pass a string to a * function that only accepts a node-set." */ fragment = xsltCreateRVT(tctxt); if (fragment == NULL) { xsltTransformError(tctxt, NULL, tctxt->inst, "exsltNodeSetFunction: Failed to create a tree fragment.\n"); tctxt->state = XSLT_STATE_STOPPED; return; } xsltRegisterLocalRVT(tctxt, fragment); strval = xmlXPathPopString (ctxt); txt = xmlNewDocText (fragment, strval); xmlAddChild((xmlNodePtr) fragment, txt); obj = xmlXPathNewNodeSet(txt); if (obj == NULL) { xsltTransformError(tctxt, NULL, tctxt->inst, "exsltNodeSetFunction: Failed to create a node set object.\n"); tctxt->state = XSLT_STATE_STOPPED; } else { /* * Mark it as a function result in order to avoid garbage * collecting of tree fragments */ xsltExtensionInstructionResultRegister(tctxt, obj); } if (strval != NULL) xmlFree (strval); valuePush (ctxt, obj); } } 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); } /** * exsltCommonRegister: * * Registers the EXSLT - Common module */ void exsltCommonRegister (void) { xsltRegisterExtModuleFunction((const xmlChar *) "node-set", EXSLT_COMMON_NAMESPACE, exsltNodeSetFunction); xsltRegisterExtModuleFunction((const xmlChar *) "object-type", EXSLT_COMMON_NAMESPACE, exsltObjectTypeFunction); xsltRegisterExtModuleElement((const xmlChar *) "document", EXSLT_COMMON_NAMESPACE, (xsltPreComputeFunction) xsltDocumentComp, (xsltTransformFunction) xsltDocumentElem); }