15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * functions.c: Implementation of the XSLT extra functions 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Reference: 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.w3.org/TR/1999/REC-xslt-19991116 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See Copyright for the status of this software. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * daniel@veillard.com 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Bjorn Reese <breese@users.sourceforge.net> for number formatting 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IN_LIBXSLT 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxslt.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_TYPES_H 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_CTYPE_H 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ctype.h> 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlmemory.h> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/parser.h> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/tree.h> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/valid.h> 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/hash.h> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlerror.h> 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xpath.h> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xpathInternals.h> 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/parserInternals.h> 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/uri.h> 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xpointer.h> 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xslt.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xsltInternals.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xsltutils.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "functions.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "extensions.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "numbersInternals.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "keys.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "documents.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_XSLT_DEBUG 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WITH_XSLT_DEBUG_FUNCTION 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Some versions of DocBook XSL use the vendor string to detect 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * supporting chunking, this is a workaround to be considered 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * in the list of decent XSLT processors <grin/> 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DOCBOOK_XSL_HACK 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltXPathFunctionLookup: 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a void * but the XSLT transformation context actually 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name: the function name 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ns_uri: the function namespace URI 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is the entry point when a function is needed by the XPath 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * interpretor. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the callback function or NULL if not found 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPathFunction 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltXPathFunctionLookup (xmlXPathContextPtr ctxt, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *name, const xmlChar *ns_uri) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFunction ret; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (name == NULL) || (ns_uri == NULL)) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (NULL); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_XSLT_DEBUG_FUNCTION 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltGenericDebug(xsltGenericDebugContext, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Lookup function {%s}%s\n", ns_uri, name); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* give priority to context-level functions */ 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = (xmlXPathFunction) xmlHashLookup2(ctxt->funcHash, name, ns_uri); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XML_CAST_FPTR(ret) = xmlHashLookup2(ctxt->funcHash, name, ns_uri); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == NULL) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xsltExtModuleFunctionLookup(name, ns_uri); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_XSLT_DEBUG_FUNCTION 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret != NULL) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltGenericDebug(xsltGenericDebugContext, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "found function %s\n", name); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Module interfaces * 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltDocumentFunctionLoadDocument(xmlXPathParserContextPtr ctxt, xmlChar* URI) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformContextPtr tctxt; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlURIPtr uri; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *fragment; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltDocumentPtr idoc; /* document info */ 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathContextPtr xptrctxt = NULL; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr resObj = NULL; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tctxt = xsltXPathGetTransformContext(ctxt); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tctxt == NULL) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "document() : internal error tctxt == NULL\n"); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uri = xmlParseURI((const char *) URI); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (uri == NULL) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(tctxt, NULL, NULL, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "document() : failed to parse URI\n"); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * check for and remove fragment identifier 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fragment = (xmlChar *)uri->fragment; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fragment != NULL) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *newURI; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uri->fragment = NULL; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newURI = xmlSaveUri(uri); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idoc = xsltLoadDocument(tctxt, newURI); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(newURI); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) idoc = xsltLoadDocument(tctxt, URI); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFreeURI(uri); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (idoc == NULL) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((URI == NULL) || 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (URI[0] == '#') || 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((tctxt->style->doc != NULL) && 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(tctxt->style->doc->URL, URI)))) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This selects the stylesheet's doc itself. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = tctxt->style->doc; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fragment != NULL) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(fragment); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = idoc->doc; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (fragment == NULL) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewNodeSet((xmlNodePtr) doc)); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* use XPointer of HTML location for fragment ID */ 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_XPTR_ENABLED 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xptrctxt = xmlXPtrNewContext(doc, NULL, NULL); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xptrctxt == NULL) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(tctxt, NULL, NULL, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "document() : internal error xptrctxt == NULL\n"); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto out_fragment; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resObj = xmlXPtrEval(fragment, xptrctxt); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeContext(xptrctxt); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(fragment); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resObj == NULL) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto out_fragment; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (resObj->type) { 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_NODESET: 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_UNDEFINED: 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_BOOLEAN: 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_NUMBER: 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_STRING: 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_POINT: 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_USERS: 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_XSLT_TREE: 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_RANGE: 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XPATH_LOCATIONSET: 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(tctxt, NULL, NULL, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "document() : XPointer does not select a node set: #%s\n", 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fragment); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto out_object; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, resObj); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)out_object: 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(resObj); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)out_fragment: 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltDocumentFunction: 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the XPath Parser context 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Implement the document() XSLT function 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * node-set document(object, node-set?) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr obj, obj2 = NULL; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *base = NULL, *URI; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((nargs < 1) || (nargs > 2)) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "document() : invalid number of args %d\n", 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nargs); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_ARITY; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->value == NULL) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "document() : invalid arg value\n"); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_TYPE; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nargs == 2) { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->value->type != XPATH_NODESET) { 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "document() : invalid arg expecting a nodeset\n"); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_TYPE; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj2 = valuePop(ctxt); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->value->type == XPATH_NODESET) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr newobj, ret; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj = valuePop(ctxt); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlXPathNewNodeSet(NULL); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj->nodesetval) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < obj->nodesetval->nodeNr; i++) { 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i])); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathStringFunction(ctxt, 1); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nargs == 2) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathObjectCopy(obj2)); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathNewNodeSet(obj->nodesetval-> 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodeTab[i])); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltDocumentFunction(ctxt, 2); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newobj = valuePop(ctxt); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newobj->nodesetval); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(newobj); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj2 != NULL) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj2); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, ret); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Make sure it's converted to a string 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathStringFunction(ctxt, 1); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->value->type != XPATH_STRING) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "document() : invalid arg expecting a string\n"); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_TYPE; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj2 != NULL) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj2); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj = valuePop(ctxt); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj->stringval == NULL) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((obj2 != NULL) && (obj2->nodesetval != NULL) && 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (obj2->nodesetval->nodeNr > 0) && 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IS_XSLT_REAL_NODE(obj2->nodesetval->nodeTab[0])) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr target; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target = obj2->nodesetval->nodeTab[0]; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((target->type == XML_ATTRIBUTE_NODE) || 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (target->type == XML_PI_NODE)) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target = ((xmlAttrPtr) target)->parent; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base = xmlNodeGetBase(target->doc, target); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformContextPtr tctxt; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tctxt = xsltXPathGetTransformContext(ctxt); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tctxt != NULL) && (tctxt->inst != NULL)) { 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base = xmlNodeGetBase(tctxt->inst->doc, tctxt->inst); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((tctxt != NULL) && (tctxt->style != NULL) && 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (tctxt->style->doc != NULL)) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base = xmlNodeGetBase(tctxt->style->doc, 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlNodePtr) tctxt->style->doc); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URI = xmlBuildURI(obj->stringval, base); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base != NULL) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(base); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (URI == NULL) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltDocumentFunctionLoadDocument( ctxt, URI ); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(URI); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj2 != NULL) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj2); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltKeyFunction: 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the XPath Parser context 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Implement the key() XSLT function 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * node-set key(string, object) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){ 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr obj1, obj2; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nargs != 2) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "key() : expects two arguments\n"); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_ARITY; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the key's value. 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj2 = valuePop(ctxt); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathStringFunction(ctxt, 1); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((obj2 == NULL) || 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "key() : invalid arg expecting a string\n"); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_TYPE; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj2); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the key's name. 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj1 = valuePop(ctxt); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((obj2->type == XPATH_NODESET) || (obj2->type == XPATH_XSLT_TREE)) { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr newobj, ret; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlXPathNewNodeSet(NULL); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj2->nodesetval != NULL) { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < obj2->nodesetval->nodeNr; i++) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathObjectCopy(obj1)); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathNewNodeSet(obj2->nodesetval->nodeTab[i])); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathStringFunction(ctxt, 1); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltKeyFunction(ctxt, 2); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newobj = valuePop(ctxt); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newobj->nodesetval); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(newobj); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, ret); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodeSetPtr nodelist = NULL; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *key = NULL, *value; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *keyURI; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformContextPtr tctxt; 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *qname, *prefix; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathContextPtr xpctxt = ctxt->context; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr tmpNode = NULL; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltDocumentPtr oldDocInfo; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tctxt = xsltXPathGetTransformContext(ctxt); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldDocInfo = tctxt->document; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xpctxt->node == NULL) { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(tctxt, NULL, tctxt->inst, 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Internal error in xsltKeyFunction(): " 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "The context node is not set on the XPath context.\n"); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tctxt->state = XSLT_STATE_STOPPED; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get the associated namespace URI if qualified name 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) qname = obj1->stringval; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = xmlSplitQName2(qname, &prefix); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key == NULL) { 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) key = xmlStrdup(obj1->stringval); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keyURI = NULL; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefix != NULL) 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(prefix); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefix != NULL) { 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keyURI = xmlXPathNsLookup(xpctxt, prefix); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (keyURI == NULL) { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(tctxt, NULL, tctxt->inst, 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "key() : prefix %s is not bound\n", prefix); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: Shouldn't we stop here? 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(prefix); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keyURI = NULL; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Force conversion of first arg to string 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, obj2); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathStringFunction(ctxt, 1); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(tctxt, NULL, tctxt->inst, 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "key() : invalid arg expecting a string\n"); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_TYPE; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj2 = valuePop(ctxt); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) value = obj2->stringval; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We need to ensure that ctxt->document is available for 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltGetKey(). 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * First find the relevant doc, which is the context node's 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * owner doc; using context->doc is not safe, since 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the doc could have been acquired via the document() function, 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * or the doc might be a Result Tree Fragment. 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * FUTURE INFO: In XSLT 2.0 the key() function takes an additional 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * argument indicating the doc to use. 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xpctxt->node->type == XML_NAMESPACE_DECL) { 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * REVISIT: This is a libxml hack! Check xpath.c for details. 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The XPath module sets the owner element of a ns-node on 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the ns->next field. 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((((xmlNsPtr) xpctxt->node)->next != NULL) && 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (((xmlNsPtr) xpctxt->node)->next->type == XML_ELEMENT_NODE)) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpNode = (xmlNodePtr) ((xmlNsPtr) xpctxt->node)->next; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpNode = xpctxt->node; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tmpNode == NULL) || (tmpNode->doc == NULL)) { 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(tctxt, NULL, tctxt->inst, 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Internal error in xsltKeyFunction(): " 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Couldn't get the doc of the XPath context node.\n"); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tctxt->document == NULL) || 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (tctxt->document->doc != tmpNode->doc)) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmpNode->doc->name && (tmpNode->doc->name[0] == ' ')) { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is a Result Tree Fragment. 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmpNode->doc->_private == NULL) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmpNode->doc->_private = xsltNewDocument(tctxt, tmpNode->doc); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmpNode->doc->_private == NULL) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tctxt->document = (xsltDocumentPtr) tmpNode->doc->_private; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * May be the initial source doc or a doc acquired via the 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * document() function. 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tctxt->document = xsltFindDocument(tctxt, tmpNode->doc); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tctxt->document == NULL) { 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(tctxt, NULL, tctxt->inst, 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Internal error in xsltKeyFunction(): " 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Could not get the document info of a context doc.\n"); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tctxt->state = XSLT_STATE_STOPPED; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Get/compute the key value. 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodelist = xsltGetKey(tctxt, key, keyURI, value); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error: 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tctxt->document = oldDocInfo; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathWrapNodeSet( 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathNodeSetMerge(NULL, nodelist))); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (key != NULL) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(key); 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj1 != NULL) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj1); 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj2 != NULL) 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj2); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltUnparsedEntityURIFunction: 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the XPath Parser context 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Implement the unparsed-entity-uri() XSLT function 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * string unparsed-entity-uri(string) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltUnparsedEntityURIFunction(xmlXPathParserContextPtr ctxt, int nargs){ 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr obj; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *str; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((nargs != 1) || (ctxt->value == NULL)) { 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltGenericError(xsltGenericErrorContext, 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "unparsed-entity-uri() : expects one string arg\n"); 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_ARITY; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj = valuePop(ctxt); 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj->type != XPATH_STRING) { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj = xmlXPathConvertString(obj); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str = obj->stringval; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str == NULL) { 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlEntityPtr entity; 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entity = xmlGetDocEntity(ctxt->context->doc, str); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entity == NULL) { 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entity->URI != NULL) 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewString(entity->URI)); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltFormatNumberFunction: 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the XPath Parser context 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Implement the format-number() XSLT function 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * string format-number(number, string, string?) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr numberObj = NULL; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr formatObj = NULL; 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr decimalObj = NULL; 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStylesheetPtr sheet; 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltDecimalFormatPtr formatValues; 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *result; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformContextPtr tctxt; 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tctxt = xsltXPathGetTransformContext(ctxt); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tctxt == NULL) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sheet = tctxt->style; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sheet == NULL) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) formatValues = sheet->decimalFormat; 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (nargs) { 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 3: 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CAST_TO_STRING; 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decimalObj = valuePop(ctxt); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) formatValues = xsltDecimalFormatGetByName(sheet, decimalObj->stringval); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (formatValues == NULL) { 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(tctxt, NULL, NULL, 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "format-number() : undeclared decimal format '%s'\n", 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decimalObj->stringval); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Intentional fall-through */ 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 2: 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CAST_TO_STRING; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) formatObj = valuePop(ctxt); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CAST_TO_NUMBER; 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) numberObj = valuePop(ctxt); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XP_ERROR(XPATH_INVALID_ARITY); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (formatValues != NULL) { 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xsltFormatNumberConversion(formatValues, 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) formatObj->stringval, 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) numberObj->floatval, 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &result) == XPATH_EXPRESSION_OK) { 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewString(result)); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(result); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(numberObj); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(formatObj); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(decimalObj); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltGenerateIdFunction: 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the XPath Parser context 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Implement the generate-id() XSLT function 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * string generate-id(node-set?) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr cur = NULL; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr obj = NULL; 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long val; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar str[30]; 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc; 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nargs == 0) { 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = ctxt->context->node; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (nargs == 1) { 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodeSetPtr nodelist; 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i, ret; 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) { 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_TYPE; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "generate-id() : invalid arg expecting a node-set\n"); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj = valuePop(ctxt); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nodelist = obj->nodesetval; 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) { 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewCString("")); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = nodelist->nodeTab[0]; 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 1;i < nodelist->nodeNr;i++) { 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == -1) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = nodelist->nodeTab[i]; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "generate-id() : invalid number of args %d\n", nargs); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_ARITY; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Okay this is ugly but should work, use the NodePtr address 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * to forge the ID 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur->type != XML_NAMESPACE_DECL) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = cur->doc; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr ns = (xmlNsPtr) cur; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ns->context != NULL) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = ns->context; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = ctxt->context->doc; 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val = (long)((char *)cur - (char *)doc); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (val >= 0) { 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf((char *)str, "idp%ld", val); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sprintf((char *)str, "idm%ld", -val); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewString(str)); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltSystemPropertyFunction: 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the XPath Parser context 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Implement the system-property() XSLT function 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * object system-property(string) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltSystemPropertyFunction(xmlXPathParserContextPtr ctxt, int nargs){ 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr obj; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *prefix, *name; 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *nsURI = NULL; 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nargs != 1) { 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "system-property() : expects one string arg\n"); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_ARITY; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "system-property() : invalid arg expecting a string\n"); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_TYPE; 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj = valuePop(ctxt); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obj->stringval == NULL) { 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = xmlSplitQName2(obj->stringval, &prefix); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name == NULL) { 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = xmlStrdup(obj->stringval); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nsURI = xmlXPathNsLookup(ctxt->context, prefix); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nsURI == NULL) { 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "system-property() : prefix %s is not bound\n", prefix); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(nsURI, XSLT_NAMESPACE)) { 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DOCBOOK_XSL_HACK 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(name, (const xmlChar *)"vendor")) { 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStylesheetPtr sheet; 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformContextPtr tctxt; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tctxt = xsltXPathGetTransformContext(ctxt); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((tctxt != NULL) && (tctxt->inst != NULL) && 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(tctxt->inst->name, BAD_CAST "variable")) && 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (tctxt->inst->parent != NULL) && 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(tctxt->inst->parent->name, 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BAD_CAST "template"))) 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sheet = tctxt->style; 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sheet = NULL; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((sheet != NULL) && (sheet->doc != NULL) && 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sheet->doc->URL != NULL) && 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrstr(sheet->doc->URL, 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (const xmlChar *)"chunk") != NULL)) { 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewString( 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (const xmlChar *)"libxslt (SAXON 6.2 compatible)")); 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewString( 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (const xmlChar *)XSLT_DEFAULT_VENDOR)); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(name, (const xmlChar *)"vendor")) { 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewString( 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (const xmlChar *)XSLT_DEFAULT_VENDOR)); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(name, (const xmlChar *)"version")) { 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewString( 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (const xmlChar *)XSLT_DEFAULT_VERSION)); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (xmlStrEqual(name, (const xmlChar *)"vendor-url")) { 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewString( 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (const xmlChar *)XSLT_DEFAULT_URL)); 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name != NULL) 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(name); 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefix != NULL) 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(prefix); 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltElementAvailableFunction: 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the XPath Parser context 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Implement the element-available() XSLT function 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * boolean element-available(string) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltElementAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){ 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr obj; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *prefix, *name; 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *nsURI = NULL; 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformContextPtr tctxt; 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nargs != 1) { 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "element-available() : expects one string arg\n"); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_ARITY; 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathStringFunction(ctxt, 1); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "element-available() : invalid arg expecting a string\n"); 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_TYPE; 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj = valuePop(ctxt); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tctxt = xsltXPathGetTransformContext(ctxt); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tctxt == NULL) { 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "element-available() : internal error tctxt == NULL\n"); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewBoolean(0)); 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = xmlSplitQName2(obj->stringval, &prefix); 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name == NULL) { 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr ns; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = xmlStrdup(obj->stringval); 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = xmlSearchNs(tctxt->inst->doc, tctxt->inst, NULL); 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ns != NULL) nsURI = xmlStrdup(ns->href); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nsURI = xmlXPathNsLookup(ctxt->context, prefix); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nsURI == NULL) { 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "element-available() : prefix %s is not bound\n", prefix); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xsltExtElementLookup(tctxt, name, nsURI) != NULL) { 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewBoolean(1)); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewBoolean(0)); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name != NULL) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(name); 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefix != NULL) 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(prefix); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltFunctionAvailableFunction: 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the XPath Parser context 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Implement the function-available() XSLT function 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * boolean function-available(string) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltFunctionAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){ 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr obj; 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *prefix, *name; 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *nsURI = NULL; 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nargs != 1) { 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "function-available() : expects one string arg\n"); 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_ARITY; 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathStringFunction(ctxt, 1); 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "function-available() : invalid arg expecting a string\n"); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_TYPE; 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) obj = valuePop(ctxt); 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = xmlSplitQName2(obj->stringval, &prefix); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name == NULL) { 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = xmlStrdup(obj->stringval); 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nsURI = xmlXPathNsLookup(ctxt->context, prefix); 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nsURI == NULL) { 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "function-available() : prefix %s is not bound\n", prefix); 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlXPathFunctionLookupNS(ctxt->context, name, nsURI) != NULL) { 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewBoolean(1)); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewBoolean(0)); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(obj); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name != NULL) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(name); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (prefix != NULL) 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(prefix); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCurrentFunction: 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the XPath Parser context 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs: the number of arguments 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Implement the current() XSLT function 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * node-set current() 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCurrentFunction(xmlXPathParserContextPtr ctxt, int nargs){ 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformContextPtr tctxt; 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nargs != 0) { 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "current() : function uses no argument\n"); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = XPATH_INVALID_ARITY; 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tctxt = xsltXPathGetTransformContext(ctxt); 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tctxt == NULL) { 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "current() : internal error tctxt == NULL\n"); 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) valuePush(ctxt, xmlXPathNewNodeSet(tctxt->node)); /* current */ 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Registration of XSLT and libxslt functions * 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltRegisterAllFunctions: 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the XPath context 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Registers all default XSLT functions in this context 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltRegisterAllFunctions(xmlXPathContextPtr ctxt) 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathRegisterFunc(ctxt, (const xmlChar *) "current", 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCurrentFunction); 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathRegisterFunc(ctxt, (const xmlChar *) "document", 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltDocumentFunction); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathRegisterFunc(ctxt, (const xmlChar *) "key", xsltKeyFunction); 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathRegisterFunc(ctxt, (const xmlChar *) "unparsed-entity-uri", 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltUnparsedEntityURIFunction); 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathRegisterFunc(ctxt, (const xmlChar *) "format-number", 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFormatNumberFunction); 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathRegisterFunc(ctxt, (const xmlChar *) "generate-id", 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltGenerateIdFunction); 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathRegisterFunc(ctxt, (const xmlChar *) "system-property", 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltSystemPropertyFunction); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathRegisterFunc(ctxt, (const xmlChar *) "element-available", 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltElementAvailableFunction); 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathRegisterFunc(ctxt, (const xmlChar *) "function-available", 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFunctionAvailableFunction); 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 994