17d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/* 27d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * functions.c: Implementation of the XSLT extra functions 37d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 47d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Reference: 57d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * http://www.w3.org/TR/1999/REC-xslt-19991116 67d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 77d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * See Copyright for the status of this software. 87d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 97d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * daniel@veillard.com 107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Bjorn Reese <breese@users.sourceforge.net> for number formatting 117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#define IN_LIBXSLT 147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "libxslt.h" 157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <string.h> 177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef HAVE_SYS_TYPES_H 197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <sys/types.h> 207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif 217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef HAVE_CTYPE_H 227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <ctype.h> 237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif 247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/xmlmemory.h> 267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/parser.h> 277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/tree.h> 287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/valid.h> 297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/hash.h> 307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/xmlerror.h> 317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/xpath.h> 327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/xpathInternals.h> 337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/parserInternals.h> 347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/uri.h> 357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include <libxml/xpointer.h> 367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "xslt.h" 377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "xsltInternals.h" 387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "xsltutils.h" 397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "functions.h" 407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "extensions.h" 417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "numbersInternals.h" 427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "keys.h" 437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#include "documents.h" 447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef WITH_XSLT_DEBUG 467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#define WITH_XSLT_DEBUG_FUNCTION 477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif 487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/* 507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Some versions of DocBook XSL use the vendor string to detect 517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * supporting chunking, this is a workaround to be considered 527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * in the list of decent XSLT processors <grin/> 537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#define DOCBOOK_XSL_HACK 557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/** 577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltXPathFunctionLookup: 587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt: a void * but the XSLT transformation context actually 597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @name: the function name 607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ns_uri: the function namespace URI 617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * This is the entry point when a function is needed by the XPath 637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * interpretor. 647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Returns the callback function or NULL if not found 667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxmlXPathFunction 687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltXPathFunctionLookup (xmlXPathContextPtr ctxt, 697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang const xmlChar *name, const xmlChar *ns_uri) { 707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFunction ret; 717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((ctxt == NULL) || (name == NULL) || (ns_uri == NULL)) 737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return (NULL); 747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef WITH_XSLT_DEBUG_FUNCTION 767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltGenericDebug(xsltGenericDebugContext, 777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "Lookup function {%s}%s\n", ns_uri, name); 787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif 797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* give priority to context-level functions */ 817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ret = (xmlXPathFunction) xmlHashLookup2(ctxt->funcHash, name, ns_uri); 837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang XML_CAST_FPTR(ret) = xmlHashLookup2(ctxt->funcHash, name, ns_uri); 857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (ret == NULL) 877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ret = xsltExtModuleFunctionLookup(name, ns_uri); 887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef WITH_XSLT_DEBUG_FUNCTION 907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (ret != NULL) 917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltGenericDebug(xsltGenericDebugContext, 927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "found function %s\n", name); 937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif 947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return(ret); 957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang} 967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/************************************************************************ 997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * * 1007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Module interfaces * 1017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * * 1027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ************************************************************************/ 1037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 1047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangstatic void 1057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltDocumentFunctionLoadDocument(xmlXPathParserContextPtr ctxt, xmlChar* URI) 1067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang{ 1077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformContextPtr tctxt; 1087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlURIPtr uri; 1097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlChar *fragment; 1107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltDocumentPtr idoc; /* document info */ 1117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlDocPtr doc; 1127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathContextPtr xptrctxt = NULL; 1137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathObjectPtr resObj = NULL; 1147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 1157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tctxt = xsltXPathGetTransformContext(ctxt); 1167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (tctxt == NULL) { 1177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(NULL, NULL, NULL, 1187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "document() : internal error tctxt == NULL\n"); 1197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 1207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 1217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 1227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 1237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang uri = xmlParseURI((const char *) URI); 1247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (uri == NULL) { 1257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(tctxt, NULL, NULL, 1267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "document() : failed to parse URI\n"); 1277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 1287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 1297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 1307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 1317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 1327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * check for and remove fragment identifier 1337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 1347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang fragment = (xmlChar *)uri->fragment; 1357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (fragment != NULL) { 1367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlChar *newURI; 1377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang uri->fragment = NULL; 1387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang newURI = xmlSaveUri(uri); 1397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang idoc = xsltLoadDocument(tctxt, newURI); 1407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(newURI); 1417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else 1427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang idoc = xsltLoadDocument(tctxt, URI); 1437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFreeURI(uri); 1447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 1457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (idoc == NULL) { 1467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((URI == NULL) || 1477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (URI[0] == '#') || 1487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ((tctxt->style->doc != NULL) && 1497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (xmlStrEqual(tctxt->style->doc->URL, URI)))) 1507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang { 1517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 1527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * This selects the stylesheet's doc itself. 1537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 1547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang doc = tctxt->style->doc; 1557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 1567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 1577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 1587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (fragment != NULL) 1597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(fragment); 1607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 1617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 1627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 1637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else 1647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang doc = idoc->doc; 1657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 1667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (fragment == NULL) { 1677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewNodeSet((xmlNodePtr) doc)); 1687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 1697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 1707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 1717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* use XPointer of HTML location for fragment ID */ 1727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef LIBXML_XPTR_ENABLED 1737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xptrctxt = xmlXPtrNewContext(doc, NULL, NULL); 1747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (xptrctxt == NULL) { 1757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(tctxt, NULL, NULL, 1767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "document() : internal error xptrctxt == NULL\n"); 1777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang goto out_fragment; 1787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 1797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 1807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang resObj = xmlXPtrEval(fragment, xptrctxt); 1817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeContext(xptrctxt); 1827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif 1837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(fragment); 1847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 1857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (resObj == NULL) 1867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang goto out_fragment; 1877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 1887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang switch (resObj->type) { 1897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang case XPATH_NODESET: 1907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang break; 1917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang case XPATH_UNDEFINED: 1927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang case XPATH_BOOLEAN: 1937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang case XPATH_NUMBER: 1947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang case XPATH_STRING: 1957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang case XPATH_POINT: 1967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang case XPATH_USERS: 1977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang case XPATH_XSLT_TREE: 1987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang case XPATH_RANGE: 1997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang case XPATH_LOCATIONSET: 2007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(tctxt, NULL, NULL, 2017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "document() : XPointer does not select a node set: #%s\n", 2027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang fragment); 2037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang goto out_object; 2047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 2057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 2067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, resObj); 2077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 2087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 2097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangout_object: 2107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(resObj); 2117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 2127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangout_fragment: 2137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 2147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang} 2157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 2167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/** 2177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltDocumentFunction: 2187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt: the XPath Parser context 2197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @nargs: the number of arguments 2207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 2217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Implement the document() XSLT function 2227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * node-set document(object, node-set?) 2237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 2247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangvoid 2257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs) 2267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang{ 2277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathObjectPtr obj, obj2 = NULL; 2287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlChar *base = NULL, *URI; 2297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 2307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 2317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((nargs < 1) || (nargs > 2)) { 2327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 2337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "document() : invalid number of args %d\n", 2347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang nargs); 2357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_ARITY; 2367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 2377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 2387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (ctxt->value == NULL) { 2397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 2407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "document() : invalid arg value\n"); 2417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_TYPE; 2427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 2437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 2447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 2457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (nargs == 2) { 2467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (ctxt->value->type != XPATH_NODESET) { 2477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 2487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "document() : invalid arg expecting a nodeset\n"); 2497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_TYPE; 2507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 2517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 2527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 2537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang obj2 = valuePop(ctxt); 2547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 2557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 2567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (ctxt->value->type == XPATH_NODESET) { 2577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang int i; 2587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathObjectPtr newobj, ret; 2597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 2607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang obj = valuePop(ctxt); 2617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ret = xmlXPathNewNodeSet(NULL); 2627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 2637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (obj->nodesetval) { 2647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang for (i = 0; i < obj->nodesetval->nodeNr; i++) { 2657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, 2667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathNewNodeSet(obj->nodesetval->nodeTab[i])); 2677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathStringFunction(ctxt, 1); 2687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (nargs == 2) { 2697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathObjectCopy(obj2)); 2707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 2717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, 2727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathNewNodeSet(obj->nodesetval-> 2737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang nodeTab[i])); 2747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 2757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltDocumentFunction(ctxt, 2); 2767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang newobj = valuePop(ctxt); 2777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, 2787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang newobj->nodesetval); 2797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(newobj); 2807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 2817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 2827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 2837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj); 2847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (obj2 != NULL) 2857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj2); 2867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, ret); 2877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 2887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 2897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 2907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Make sure it's converted to a string 2917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 2927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathStringFunction(ctxt, 1); 2937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (ctxt->value->type != XPATH_STRING) { 2947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 2957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "document() : invalid arg expecting a string\n"); 2967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_TYPE; 2977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (obj2 != NULL) 2987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj2); 2997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 3007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 3017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang obj = valuePop(ctxt); 3027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (obj->stringval == NULL) { 3037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 3047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 3057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((obj2 != NULL) && (obj2->nodesetval != NULL) && 3067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (obj2->nodesetval->nodeNr > 0) && 3077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang IS_XSLT_REAL_NODE(obj2->nodesetval->nodeTab[0])) { 3087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlNodePtr target; 3097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 3107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang target = obj2->nodesetval->nodeTab[0]; 3117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((target->type == XML_ATTRIBUTE_NODE) || 3127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (target->type == XML_PI_NODE)) { 3137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang target = ((xmlAttrPtr) target)->parent; 3147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 3157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang base = xmlNodeGetBase(target->doc, target); 3167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 3177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformContextPtr tctxt; 3187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 3197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tctxt = xsltXPathGetTransformContext(ctxt); 3207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((tctxt != NULL) && (tctxt->inst != NULL)) { 3217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang base = xmlNodeGetBase(tctxt->inst->doc, tctxt->inst); 3227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else if ((tctxt != NULL) && (tctxt->style != NULL) && 3237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (tctxt->style->doc != NULL)) { 3247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang base = xmlNodeGetBase(tctxt->style->doc, 3257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (xmlNodePtr) tctxt->style->doc); 3267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 3277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 3287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang URI = xmlBuildURI(obj->stringval, base); 3297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (base != NULL) 3307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(base); 3317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (URI == NULL) { 3327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 3337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 3347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltDocumentFunctionLoadDocument( ctxt, URI ); 3357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(URI); 3367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 3377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 3387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj); 3397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (obj2 != NULL) 3407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj2); 3417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang} 3427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 3437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/** 3447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltKeyFunction: 3457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt: the XPath Parser context 3467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @nargs: the number of arguments 3477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 3487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Implement the key() XSLT function 3497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * node-set key(string, object) 3507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 3517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangvoid 3527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltKeyFunction(xmlXPathParserContextPtr ctxt, int nargs){ 3537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathObjectPtr obj1, obj2; 3547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 3557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (nargs != 2) { 3567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 3577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "key() : expects two arguments\n"); 3587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_ARITY; 3597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 3607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 3617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 3627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 3637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Get the key's value. 3647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 3657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang obj2 = valuePop(ctxt); 3667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathStringFunction(ctxt, 1); 3677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((obj2 == NULL) || 3687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { 3697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 3707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "key() : invalid arg expecting a string\n"); 3717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_TYPE; 3727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj2); 3737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 3747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 3757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 3767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 3777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Get the key's name. 3787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 3797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang obj1 = valuePop(ctxt); 3807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 3817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((obj2->type == XPATH_NODESET) || (obj2->type == XPATH_XSLT_TREE)) { 3827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang int i; 3837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathObjectPtr newobj, ret; 3847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 3857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ret = xmlXPathNewNodeSet(NULL); 3867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 3877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (obj2->nodesetval != NULL) { 3887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang for (i = 0; i < obj2->nodesetval->nodeNr; i++) { 3897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathObjectCopy(obj1)); 3907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, 3917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathNewNodeSet(obj2->nodesetval->nodeTab[i])); 3927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathStringFunction(ctxt, 1); 3937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltKeyFunction(ctxt, 2); 3947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang newobj = valuePop(ctxt); 3957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ret->nodesetval = xmlXPathNodeSetMerge(ret->nodesetval, 3967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang newobj->nodesetval); 3977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(newobj); 3987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 3997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 4007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, ret); 4017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 4027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlNodeSetPtr nodelist = NULL; 4037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlChar *key = NULL, *value; 4047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang const xmlChar *keyURI; 4057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformContextPtr tctxt; 4067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlChar *qname, *prefix; 4077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathContextPtr xpctxt = ctxt->context; 4087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlNodePtr tmpNode = NULL; 4097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltDocumentPtr oldDocInfo; 4107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 4117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tctxt = xsltXPathGetTransformContext(ctxt); 4127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 4137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang oldDocInfo = tctxt->document; 4147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 4157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (xpctxt->node == NULL) { 4167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(tctxt, NULL, tctxt->inst, 4177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "Internal error in xsltKeyFunction(): " 4187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "The context node is not set on the XPath context.\n"); 4197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tctxt->state = XSLT_STATE_STOPPED; 4207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang goto error; 4217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 4227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 4237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Get the associated namespace URI if qualified name 4247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 4257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang qname = obj1->stringval; 4267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang key = xmlSplitQName2(qname, &prefix); 4277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (key == NULL) { 4287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang key = xmlStrdup(obj1->stringval); 4297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang keyURI = NULL; 4307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (prefix != NULL) 4317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(prefix); 4327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 4337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (prefix != NULL) { 4347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang keyURI = xmlXPathNsLookup(xpctxt, prefix); 4357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (keyURI == NULL) { 4367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(tctxt, NULL, tctxt->inst, 4377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "key() : prefix %s is not bound\n", prefix); 4387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 4397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * TODO: Shouldn't we stop here? 4407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 4417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 4427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(prefix); 4437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 4447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang keyURI = NULL; 4457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 4467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 4477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 4487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 4497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Force conversion of first arg to string 4507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 4517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, obj2); 4527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathStringFunction(ctxt, 1); 4537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { 4547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(tctxt, NULL, tctxt->inst, 4557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "key() : invalid arg expecting a string\n"); 4567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_TYPE; 4577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang goto error; 4587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 4597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang obj2 = valuePop(ctxt); 4607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang value = obj2->stringval; 4617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 4627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 4637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * We need to ensure that ctxt->document is available for 4647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltGetKey(). 4657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * First find the relevant doc, which is the context node's 4667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * owner doc; using context->doc is not safe, since 4677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * the doc could have been acquired via the document() function, 4687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * or the doc might be a Result Tree Fragment. 4697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * FUTURE INFO: In XSLT 2.0 the key() function takes an additional 4707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * argument indicating the doc to use. 4717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 4727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (xpctxt->node->type == XML_NAMESPACE_DECL) { 4737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 4747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * REVISIT: This is a libxml hack! Check xpath.c for details. 4757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * The XPath module sets the owner element of a ns-node on 4767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * the ns->next field. 4777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 4787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((((xmlNsPtr) xpctxt->node)->next != NULL) && 4797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (((xmlNsPtr) xpctxt->node)->next->type == XML_ELEMENT_NODE)) 4807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang { 4817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tmpNode = (xmlNodePtr) ((xmlNsPtr) xpctxt->node)->next; 4827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 4837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else 4847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tmpNode = xpctxt->node; 4857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 4867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((tmpNode == NULL) || (tmpNode->doc == NULL)) { 4877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(tctxt, NULL, tctxt->inst, 4887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "Internal error in xsltKeyFunction(): " 4897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "Couldn't get the doc of the XPath context node.\n"); 4907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang goto error; 4917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 4927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 4937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((tctxt->document == NULL) || 4947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (tctxt->document->doc != tmpNode->doc)) 4957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang { 4967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (tmpNode->doc->name && (tmpNode->doc->name[0] == ' ')) { 4977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 4987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * This is a Result Tree Fragment. 4997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 5007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (tmpNode->doc->_private == NULL) { 5017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tmpNode->doc->_private = xsltNewDocument(tctxt, tmpNode->doc); 5027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (tmpNode->doc->_private == NULL) 5037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang goto error; 5047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 5057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tctxt->document = (xsltDocumentPtr) tmpNode->doc->_private; 5067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 5077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 5087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * May be the initial source doc or a doc acquired via the 5097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * document() function. 5107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 5117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tctxt->document = xsltFindDocument(tctxt, tmpNode->doc); 5127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 5137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (tctxt->document == NULL) { 5147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(tctxt, NULL, tctxt->inst, 5157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "Internal error in xsltKeyFunction(): " 5167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "Could not get the document info of a context doc.\n"); 5177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tctxt->state = XSLT_STATE_STOPPED; 5187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang goto error; 5197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 5207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 5217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 5227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Get/compute the key value. 5237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 5247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang nodelist = xsltGetKey(tctxt, key, keyURI, value); 5257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 5267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangerror: 5277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tctxt->document = oldDocInfo; 5287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathWrapNodeSet( 5297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathNodeSetMerge(NULL, nodelist))); 5307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (key != NULL) 5317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(key); 5327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 5337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 5347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (obj1 != NULL) 5357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj1); 5367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (obj2 != NULL) 5377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj2); 5387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang} 5397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 5407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/** 5417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltUnparsedEntityURIFunction: 5427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt: the XPath Parser context 5437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @nargs: the number of arguments 5447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 5457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Implement the unparsed-entity-uri() XSLT function 5467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * string unparsed-entity-uri(string) 5477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 5487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangvoid 5497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltUnparsedEntityURIFunction(xmlXPathParserContextPtr ctxt, int nargs){ 5507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathObjectPtr obj; 5517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlChar *str; 5527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 5537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((nargs != 1) || (ctxt->value == NULL)) { 5547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltGenericError(xsltGenericErrorContext, 5557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "unparsed-entity-uri() : expects one string arg\n"); 5567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_ARITY; 5577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 5587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 5597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang obj = valuePop(ctxt); 5607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (obj->type != XPATH_STRING) { 5617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang obj = xmlXPathConvertString(obj); 5627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 5637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 5647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang str = obj->stringval; 5657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (str == NULL) { 5667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); 5677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 5687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlEntityPtr entity; 5697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 5707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang entity = xmlGetDocEntity(ctxt->context->doc, str); 5717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (entity == NULL) { 5727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); 5737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 5747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (entity->URI != NULL) 5757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewString(entity->URI)); 5767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang else 5777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); 5787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 5797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 5807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj); 5817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang} 5827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 5837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/** 5847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltFormatNumberFunction: 5857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt: the XPath Parser context 5867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @nargs: the number of arguments 5877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 5887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Implement the format-number() XSLT function 5897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * string format-number(number, string, string?) 5907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 5917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangvoid 5927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) 5937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang{ 5947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathObjectPtr numberObj = NULL; 5957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathObjectPtr formatObj = NULL; 5967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathObjectPtr decimalObj = NULL; 5977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltStylesheetPtr sheet; 5987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltDecimalFormatPtr formatValues; 5997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlChar *result; 6007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformContextPtr tctxt; 6017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 6027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tctxt = xsltXPathGetTransformContext(ctxt); 6037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (tctxt == NULL) 6047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 6057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang sheet = tctxt->style; 6067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (sheet == NULL) 6077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 6087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang formatValues = sheet->decimalFormat; 6097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 6107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang switch (nargs) { 6117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang case 3: 6127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang CAST_TO_STRING; 6137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang decimalObj = valuePop(ctxt); 6147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang formatValues = xsltDecimalFormatGetByName(sheet, decimalObj->stringval); 6157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (formatValues == NULL) { 6167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(tctxt, NULL, NULL, 6177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "format-number() : undeclared decimal format '%s'\n", 6187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang decimalObj->stringval); 6197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 6207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* Intentional fall-through */ 6217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang case 2: 6227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang CAST_TO_STRING; 6237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang formatObj = valuePop(ctxt); 6247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang CAST_TO_NUMBER; 6257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang numberObj = valuePop(ctxt); 6267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang break; 6277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang default: 6287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang XP_ERROR(XPATH_INVALID_ARITY); 6297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 6307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 6317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (formatValues != NULL) { 6327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (xsltFormatNumberConversion(formatValues, 6337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang formatObj->stringval, 6347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang numberObj->floatval, 6357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang &result) == XPATH_EXPRESSION_OK) { 6367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewString(result)); 6377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(result); 6387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 6397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 6407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 6417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(numberObj); 6427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(formatObj); 6437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(decimalObj); 6447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang} 6457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 6467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/** 6477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltGenerateIdFunction: 6487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt: the XPath Parser context 6497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @nargs: the number of arguments 6507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 6517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Implement the generate-id() XSLT function 6527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * string generate-id(node-set?) 6537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 6547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangvoid 6557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){ 6567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlNodePtr cur = NULL; 6577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang unsigned long val; 6587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlChar str[20]; 6597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 6607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (nargs == 0) { 6617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang cur = ctxt->context->node; 6627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else if (nargs == 1) { 6637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathObjectPtr obj; 6647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlNodeSetPtr nodelist; 6657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang int i, ret; 6667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 6677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) { 6687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_TYPE; 6697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 6707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "generate-id() : invalid arg expecting a node-set\n"); 6717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 6727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 6737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang obj = valuePop(ctxt); 6747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang nodelist = obj->nodesetval; 6757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) { 6767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj); 6777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewCString("")); 6787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 6797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 6807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang cur = nodelist->nodeTab[0]; 6817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang for (i = 1;i < nodelist->nodeNr;i++) { 6827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ret = xmlXPathCmpNodes(cur, nodelist->nodeTab[i]); 6837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (ret == -1) 6847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang cur = nodelist->nodeTab[i]; 6857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 6867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj); 6877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 6887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 6897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "generate-id() : invalid number of args %d\n", nargs); 6907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_ARITY; 6917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 6927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 6937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang /* 6947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Okay this is ugly but should work, use the NodePtr address 6957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * to forge the ID 6967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 6977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang val = (unsigned long)((char *)cur - (char *)0); 6987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang val /= sizeof(xmlNode); 6997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang sprintf((char *)str, "id%ld", val); 7007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewString(str)); 7017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang} 7027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 7037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/** 7047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltSystemPropertyFunction: 7057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt: the XPath Parser context 7067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @nargs: the number of arguments 7077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 7087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Implement the system-property() XSLT function 7097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * object system-property(string) 7107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 7117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangvoid 7127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltSystemPropertyFunction(xmlXPathParserContextPtr ctxt, int nargs){ 7137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathObjectPtr obj; 7147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlChar *prefix, *name; 7157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang const xmlChar *nsURI = NULL; 7167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 7177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (nargs != 1) { 7187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 7197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "system-property() : expects one string arg\n"); 7207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_ARITY; 7217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 7227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 7237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { 7247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 7257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "system-property() : invalid arg expecting a string\n"); 7267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_TYPE; 7277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 7287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 7297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang obj = valuePop(ctxt); 7307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (obj->stringval == NULL) { 7317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); 7327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 7337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang name = xmlSplitQName2(obj->stringval, &prefix); 7347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (name == NULL) { 7357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang name = xmlStrdup(obj->stringval); 7367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 7377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang nsURI = xmlXPathNsLookup(ctxt->context, prefix); 7387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (nsURI == NULL) { 7397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 7407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "system-property() : prefix %s is not bound\n", prefix); 7417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 7427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 7437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 7447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (xmlStrEqual(nsURI, XSLT_NAMESPACE)) { 7457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#ifdef DOCBOOK_XSL_HACK 7467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (xmlStrEqual(name, (const xmlChar *)"vendor")) { 7477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltStylesheetPtr sheet; 7487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformContextPtr tctxt; 7497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 7507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tctxt = xsltXPathGetTransformContext(ctxt); 7517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((tctxt != NULL) && (tctxt->inst != NULL) && 7527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (xmlStrEqual(tctxt->inst->name, BAD_CAST "variable")) && 7537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (tctxt->inst->parent != NULL) && 7547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (xmlStrEqual(tctxt->inst->parent->name, 7557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang BAD_CAST "template"))) 7567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang sheet = tctxt->style; 7577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang else 7587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang sheet = NULL; 7597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((sheet != NULL) && (sheet->doc != NULL) && 7607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (sheet->doc->URL != NULL) && 7617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (xmlStrstr(sheet->doc->URL, 7627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (const xmlChar *)"chunk") != NULL)) { 7637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewString( 7647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (const xmlChar *)"libxslt (SAXON 6.2 compatible)")); 7657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 7667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 7677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewString( 7687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (const xmlChar *)XSLT_DEFAULT_VENDOR)); 7697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 7707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else 7717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#else 7727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (xmlStrEqual(name, (const xmlChar *)"vendor")) { 7737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewString( 7747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (const xmlChar *)XSLT_DEFAULT_VENDOR)); 7757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else 7767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang#endif 7777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (xmlStrEqual(name, (const xmlChar *)"version")) { 7787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewString( 7797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (const xmlChar *)XSLT_DEFAULT_VERSION)); 7807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else if (xmlStrEqual(name, (const xmlChar *)"vendor-url")) { 7817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewString( 7827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang (const xmlChar *)XSLT_DEFAULT_URL)); 7837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 7847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewString((const xmlChar *)"")); 7857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 7867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 7877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (name != NULL) 7887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(name); 7897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (prefix != NULL) 7907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(prefix); 7917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 7927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj); 7937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang} 7947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 7957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/** 7967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltElementAvailableFunction: 7977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt: the XPath Parser context 7987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @nargs: the number of arguments 7997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 8007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Implement the element-available() XSLT function 8017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * boolean element-available(string) 8027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 8037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangvoid 8047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltElementAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){ 8057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathObjectPtr obj; 8067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlChar *prefix, *name; 8077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang const xmlChar *nsURI = NULL; 8087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformContextPtr tctxt; 8097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 8107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (nargs != 1) { 8117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 8127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "element-available() : expects one string arg\n"); 8137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_ARITY; 8147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 8157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 8167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathStringFunction(ctxt, 1); 8177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { 8187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 8197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "element-available() : invalid arg expecting a string\n"); 8207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_TYPE; 8217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 8227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 8237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang obj = valuePop(ctxt); 8247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tctxt = xsltXPathGetTransformContext(ctxt); 8257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (tctxt == NULL) { 8267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 8277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "element-available() : internal error tctxt == NULL\n"); 8287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj); 8297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewBoolean(0)); 8307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 8317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 8327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 8337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 8347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang name = xmlSplitQName2(obj->stringval, &prefix); 8357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (name == NULL) { 8367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlNsPtr ns; 8377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 8387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang name = xmlStrdup(obj->stringval); 8397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ns = xmlSearchNs(tctxt->inst->doc, tctxt->inst, NULL); 8407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (ns != NULL) nsURI = xmlStrdup(ns->href); 8417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 8427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang nsURI = xmlXPathNsLookup(ctxt->context, prefix); 8437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (nsURI == NULL) { 8447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 8457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "element-available() : prefix %s is not bound\n", prefix); 8467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 8477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 8487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 8497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (xsltExtElementLookup(tctxt, name, nsURI) != NULL) { 8507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewBoolean(1)); 8517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 8527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewBoolean(0)); 8537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 8547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 8557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj); 8567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (name != NULL) 8577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(name); 8587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (prefix != NULL) 8597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(prefix); 8607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang} 8617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 8627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/** 8637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltFunctionAvailableFunction: 8647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt: the XPath Parser context 8657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @nargs: the number of arguments 8667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 8677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Implement the function-available() XSLT function 8687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * boolean function-available(string) 8697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 8707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangvoid 8717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltFunctionAvailableFunction(xmlXPathParserContextPtr ctxt, int nargs){ 8727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathObjectPtr obj; 8737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlChar *prefix, *name; 8747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang const xmlChar *nsURI = NULL; 8757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 8767d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (nargs != 1) { 8777d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 8787d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "function-available() : expects one string arg\n"); 8797d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_ARITY; 8807d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 8817d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 8827d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathStringFunction(ctxt, 1); 8837d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_STRING)) { 8847d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 8857d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "function-available() : invalid arg expecting a string\n"); 8867d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_TYPE; 8877d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 8887d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 8897d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang obj = valuePop(ctxt); 8907d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 8917d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang name = xmlSplitQName2(obj->stringval, &prefix); 8927d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (name == NULL) { 8937d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang name = xmlStrdup(obj->stringval); 8947d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 8957d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang nsURI = xmlXPathNsLookup(ctxt->context, prefix); 8967d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (nsURI == NULL) { 8977d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 8987d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "function-available() : prefix %s is not bound\n", prefix); 8997d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 9007d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 9017d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 9027d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (xmlXPathFunctionLookupNS(ctxt->context, name, nsURI) != NULL) { 9037d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewBoolean(1)); 9047d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 9057d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewBoolean(0)); 9067d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 9077d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 9087d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathFreeObject(obj); 9097d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (name != NULL) 9107d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(name); 9117d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (prefix != NULL) 9127d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlFree(prefix); 9137d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang} 9147d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 9157d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/** 9167d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltCurrentFunction: 9177d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt: the XPath Parser context 9187d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @nargs: the number of arguments 9197d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 9207d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Implement the current() XSLT function 9217d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * node-set current() 9227d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 9237d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangstatic void 9247d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltCurrentFunction(xmlXPathParserContextPtr ctxt, int nargs){ 9257d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformContextPtr tctxt; 9267d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 9277d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (nargs != 0) { 9287d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 9297d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "current() : function uses no argument\n"); 9307d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ctxt->error = XPATH_INVALID_ARITY; 9317d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang return; 9327d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 9337d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang tctxt = xsltXPathGetTransformContext(ctxt); 9347d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang if (tctxt == NULL) { 9357d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL, 9367d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang "current() : internal error tctxt == NULL\n"); 9377d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewNodeSet(NULL)); 9387d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } else { 9397d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang valuePush(ctxt, xmlXPathNewNodeSet(tctxt->node)); /* current */ 9407d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang } 9417d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang} 9427d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 9437d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/************************************************************************ 9447d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * * 9457d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Registration of XSLT and libxslt functions * 9467d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * * 9477d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang ************************************************************************/ 9487d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang 9497d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang/** 9507d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * xsltRegisterAllFunctions: 9517d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * @ctxt: the XPath context 9527d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * 9537d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang * Registers all default XSLT functions in this context 9547d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang */ 9557d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wangvoid 9567d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) WangxsltRegisterAllFunctions(xmlXPathContextPtr ctxt) 9577d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang{ 9587d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathRegisterFunc(ctxt, (const xmlChar *) "current", 9597d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltCurrentFunction); 9607d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathRegisterFunc(ctxt, (const xmlChar *) "document", 9617d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltDocumentFunction); 9627d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathRegisterFunc(ctxt, (const xmlChar *) "key", xsltKeyFunction); 9637d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathRegisterFunc(ctxt, (const xmlChar *) "unparsed-entity-uri", 9647d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltUnparsedEntityURIFunction); 9657d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathRegisterFunc(ctxt, (const xmlChar *) "format-number", 9667d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltFormatNumberFunction); 9677d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathRegisterFunc(ctxt, (const xmlChar *) "generate-id", 9687d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltGenerateIdFunction); 9697d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathRegisterFunc(ctxt, (const xmlChar *) "system-property", 9707d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltSystemPropertyFunction); 9717d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathRegisterFunc(ctxt, (const xmlChar *) "element-available", 9727d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltElementAvailableFunction); 9737d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xmlXPathRegisterFunc(ctxt, (const xmlChar *) "function-available", 9747d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang xsltFunctionAvailableFunction); 9757d1dabff1598661db0018d89d16cca02f7c31ae2Shimeng (Simon) Wang} 976