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