summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--libexslt/Makefile.am3
-rw-r--r--libexslt/exslt.c1
-rw-r--r--libexslt/exslt.h2
-rw-r--r--libexslt/saxon.c186
-rw-r--r--tests/exslt/common/object-type.1.out2
-rw-r--r--tests/extensions/evaluate.xsl16
-rw-r--r--tests/extensions/list.out5
-rw-r--r--tests/extensions/list.xsl8
9 files changed, 214 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index d7e92d38..35017ca4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Sun Oct 7 18:53:34 CEST 2001 Thomas Broyer <tbroyer@ltgt.net>
+
+ * libexslt/saxon.c libexslt/Makefile.am libexslt/exslt.[ch]:
+ added implementation of SAXON expression(), eval() and
+ evaluate() functions.
+ See http://saxon.sourceforge.net/saxon6.4.4/extensions.html
+ * tests/extension/evaluate.xsl tests/extension/list.{xsl,out}:
+ modified to use SAXON namespace (functions are not registered
+ in the LibXSLT namespace)
+ * tests/exslt/common/object-type.1.out: modified to take account
+ of the new saxon:expression function
+
Sun Oct 7 13:15:33 CEST 2001 Daniel Veillard <daniel@veillard.com>
* libxslt/numbers.c: fixed bug #61070, number ANY formatting
diff --git a/libexslt/Makefile.am b/libexslt/Makefile.am
index d297676f..c50fa89b 100644
--- a/libexslt/Makefile.am
+++ b/libexslt/Makefile.am
@@ -19,7 +19,8 @@ libexslt_la_SOURCES = \
sets.c \
functions.c \
strings.c \
- date.c
+ date.c \
+ saxon.c
libexslt_la_LIBADD = $(EXTRA_LIBS)
libexslt_la_LDFLAGS = -version-info @LIBEXSLT_VERSION_INFO@
diff --git a/libexslt/exslt.c b/libexslt/exslt.c
index 32d88106..50082fde 100644
--- a/libexslt/exslt.c
+++ b/libexslt/exslt.c
@@ -28,5 +28,6 @@ exsltRegisterAll (void) {
exsltFuncRegister();
exsltStrRegister();
exsltDateRegister();
+ exsltSaxonRegister();
}
diff --git a/libexslt/exslt.h b/libexslt/exslt.h
index 5d57937a..0bb53eaf 100644
--- a/libexslt/exslt.h
+++ b/libexslt/exslt.h
@@ -16,6 +16,7 @@ LIBEXSLT_PUBLIC extern const int exsltLibxmlVersion;
#define EXSLT_FUNCTIONS_NAMESPACE ((const xmlChar *) "http://exslt.org/functions")
#define EXSLT_STRINGS_NAMESPACE ((const xmlChar *) "http://exslt.org/strings")
#define EXSLT_DATE_NAMESPACE ((const xmlChar *) "http://exslt.org/dates-and-times")
+#define SAXON_NAMESPACE ((const xmlChar *) "http://icl.com/saxon")
void exsltCommonRegister (void);
void exsltMathRegister (void);
@@ -23,6 +24,7 @@ void exsltSetsRegister (void);
void exsltFuncRegister (void);
void exsltStrRegister (void);
void exsltDateRegister (void);
+void exsltSaxonRegister (void);
void exsltRegisterAll (void);
diff --git a/libexslt/saxon.c b/libexslt/saxon.c
new file mode 100644
index 00000000..2a8325e6
--- /dev/null
+++ b/libexslt/saxon.c
@@ -0,0 +1,186 @@
+#include <libxml/tree.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/parser.h>
+
+#include <libxslt/xsltconfig.h>
+#include <libxslt/xsltutils.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/extensions.h>
+
+#include "exslt.h"
+
+/**
+ * exsltSaxonInit:
+ * @ctxt: an XSLT transformation context
+ * @URI: the namespace URI for the extension
+ *
+ * Initializes the SAXON module.
+ *
+ * Returns the data for this transformation
+ */
+static xmlHashTablePtr
+exsltSaxonInit (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
+ const xmlChar *URI ATTRIBUTE_UNUSED) {
+ return xmlHashCreate(1);
+}
+
+/**
+ * exsltSaxonShutdown:
+ * @ctxt: an XSLT transformation context
+ * @URI: the namespace URI for the extension
+ * @data: the module data to free up
+ *
+ * Shutdown the SAXON extension module
+ */
+static void
+exsltSaxonShutdown (xsltTransformContextPtr ctxt ATTRIBUTE_UNUSED,
+ const xmlChar *URI ATTRIBUTE_UNUSED,
+ xmlHashTablePtr data) {
+ xmlHashFree(data, (xmlHashDeallocator) xmlXPathFreeCompExpr);
+}
+
+
+/**
+ * exsltSaxonExpressionFunction:
+ * @ctxt: an XPath parser context
+ * @nargs: the number of arguments
+ *
+ * The supplied string must contain an XPath expression. The result of
+ * the function is a stored expression, which may be supplied as an
+ * argument to other extension functions such as saxon:eval(),
+ * saxon:sum() and saxon:distinct(). The result of the expression will
+ * usually depend on the current node. The expression may contain
+ * references to variables that are in scope at the point where
+ * saxon:expression() is called: these variables will be replaced in
+ * the stored expression with the values they take at the time
+ * saxon:expression() is called, not the values of the variables at
+ * the time the stored expression is evaluated. Similarly, if the
+ * expression contains namespace prefixes, these are interpreted in
+ * terms of the namespace declarations in scope at the point where the
+ * saxon:expression() function is called, not those in scope where the
+ * stored expression is evaluated.
+ *
+ * TODO: current implementation doesn't conform to SAXON behaviour
+ * regarding context and namespaces.
+ */
+static void
+exsltSaxonExpressionFunction (xmlXPathParserContextPtr ctxt, int nargs) {
+ xmlChar *arg;
+ xmlXPathCompExprPtr ret;
+ xmlHashTablePtr hash;
+ xsltTransformContextPtr tctxt = xsltXPathGetTransformContext(ctxt);
+
+ if (nargs != 1) {
+ xmlXPathSetArityError(ctxt);
+ return;
+ }
+
+ arg = xmlXPathPopString(ctxt);
+ if (xmlXPathCheckError(ctxt) || (arg == NULL)) {
+ xmlXPathSetTypeError(ctxt);
+ return;
+ }
+
+ hash = (xmlHashTablePtr) xsltGetExtData(tctxt->style,
+ ctxt->context->functionURI);
+
+ ret = xmlHashLookup(hash, arg);
+ if (ret != NULL)
+ goto done;
+
+ ret = xmlXPathCompile(arg);
+
+ xmlHashAddEntry(hash, arg, (void *) ret);
+
+done:
+ xmlFree(arg);
+
+ xmlXPathReturnExternal(ctxt, ret);
+}
+
+/**
+ * exsltSaxonEvalFunction:
+ * @ctxt: an XPath parser context
+ * @nargs: number of arguments
+ *
+ * Implements de SAXON eval() function:
+ * object saxon:eval (saxon:stored-expression)
+ * Returns the result of evaluating the supplied stored expression.
+ * A stored expression may be obtained as the result of calling
+ * the saxon:expression() function.
+ * The stored expression is evaluated in the current context, that
+ * is, the context node is the current node, and the context position
+ * and context size are the same as the result of calling position()
+ * or last() respectively.
+ */
+static void
+exsltSaxonEvalFunction (xmlXPathParserContextPtr ctxt, int nargs) {
+ xmlXPathCompExprPtr expr;
+ xmlXPathObjectPtr ret;
+
+ if (nargs != 1) {
+ xmlXPathSetArityError(ctxt);
+ return;
+ }
+
+ if (!xmlXPathStackIsExternal(ctxt)) {
+ xmlXPathSetTypeError(ctxt);
+ return;
+ }
+
+ expr = (xmlXPathCompExprPtr) xmlXPathPopExternal(ctxt);
+
+ ret = xmlXPathCompiledEval(expr, ctxt->context);
+
+ valuePush(ctxt, ret);
+}
+
+/**
+ * exsltSaxonEvaluateFunction:
+ * @ctxt: an XPath parser context
+ * @nargs: number of arguments
+ *
+ * Implements the SAXON evaluate() function
+ * object saxon:evaluate (string)
+ * The supplied string must contain an XPath expression. The result of
+ * the function is the result of evaluating the XPath expression. This
+ * is useful where an expression needs to be constructed at run-time or
+ * passed to the stylesheet as a parameter, for example where the sort
+ * key is determined dynamically. The context for the expression (e.g.
+ * which variables and namespaces are available) is exactly the same as
+ * if the expression were written explicitly at this point in the
+ * stylesheet. The function saxon:evaluate(string) is shorthand for
+ * saxon:eval(saxon:expression(string)).
+ */
+static void
+exsltSaxonEvaluateFunction (xmlXPathParserContextPtr ctxt, int nargs) {
+ if (nargs != 1) {
+ xmlXPathSetArityError(ctxt);
+ return;
+ }
+
+ exsltSaxonExpressionFunction(ctxt, 1);
+ exsltSaxonEvalFunction(ctxt, 1);
+}
+
+/**
+ * exsltSaxonRegister:
+ *
+ * Registers the SAXON extension module
+ */
+void
+exsltSaxonRegister (void) {
+ xsltRegisterExtModule (SAXON_NAMESPACE,
+ (xsltExtInitFunction) exsltSaxonInit,
+ (xsltExtShutdownFunction) exsltSaxonShutdown);
+ xsltRegisterExtModuleFunction((const xmlChar *) "expression",
+ SAXON_NAMESPACE,
+ exsltSaxonExpressionFunction);
+ xsltRegisterExtModuleFunction((const xmlChar *) "eval",
+ SAXON_NAMESPACE,
+ exsltSaxonEvalFunction);
+ xsltRegisterExtModuleFunction((const xmlChar *) "evaluate",
+ SAXON_NAMESPACE,
+ exsltSaxonEvaluateFunction);
+}
diff --git a/tests/exslt/common/object-type.1.out b/tests/exslt/common/object-type.1.out
index e21cdcaa..81375b5e 100644
--- a/tests/exslt/common/object-type.1.out
+++ b/tests/exslt/common/object-type.1.out
@@ -5,5 +5,5 @@
boolean;
node-set;
RTF;
- ;
+ external;
</out>
diff --git a/tests/extensions/evaluate.xsl b/tests/extensions/evaluate.xsl
index a58470f6..c44bfc8c 100644
--- a/tests/extensions/evaluate.xsl
+++ b/tests/extensions/evaluate.xsl
@@ -1,24 +1,24 @@
<?xml version='1.0'?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns:libxslt="http://xmlsoft.org/XSLT/namespace"
+ xmlns:saxon="http://icl.com/saxon"
version='1.0'>
-<xsl:variable name="expression" select="libxslt:expression('doc/two')"/>
+<xsl:variable name="expression" select="saxon:expression('doc/two')"/>
<xsl:template match="/">
<xsl:variable name="string">doc/one</xsl:variable>
- <xsl:value-of select="libxslt:evaluate($string)"/>
- <xsl:value-of select="count(libxslt:evaluate('/doc/one')/../*)"/>
- <xsl:value-of select="libxslt:evaluate(/doc/three)"/>
- <xsl:value-of select="libxslt:eval($expression)"/>
+ <xsl:value-of select="saxon:evaluate($string)"/>
+ <xsl:value-of select="count(saxon:evaluate('/doc/one')/../*)"/>
+ <xsl:value-of select="saxon:evaluate(/doc/three)"/>
+ <xsl:value-of select="saxon:eval($expression)"/>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="four">
<xsl:variable name="string">doc/one</xsl:variable>
- <xsl:value-of select="libxslt:evaluate($string)"/>
- <xsl:value-of select="libxslt:eval($expression)"/>
+ <xsl:value-of select="saxon:evaluate($string)"/>
+ <xsl:value-of select="saxon:eval($expression)"/>
</xsl:template>
<xsl:template match="text()"/>
diff --git a/tests/extensions/list.out b/tests/extensions/list.out
index c910ba08..e2d9ce12 100644
--- a/tests/extensions/list.out
+++ b/tests/extensions/list.out
@@ -30,14 +30,11 @@ saxon:output available
xalanredirect:write available
xt:document available
libxslt:debug available
- === 9 Extension functions:
+ === 6 Extension functions:
libxslt:node-set() available
saxon:node-set() available
xt:node-set() available
-libxslt:evaluate() available
saxon:evaluate() available
-libxslt:expression() available
saxon:expression() available
-libxslt:eval() available
saxon:eval() available
diff --git a/tests/extensions/list.xsl b/tests/extensions/list.xsl
index d4fc6693..0523342b 100644
--- a/tests/extensions/list.xsl
+++ b/tests/extensions/list.xsl
@@ -69,7 +69,7 @@
</xsl:if>
<xsl:if test="element-available('libxslt:debug')">libxslt:debug available
</xsl:if>
-<xsl:text> === 9 Extension functions:
+<xsl:text> === 6 Extension functions:
</xsl:text>
<xsl:if test="function-available('libxslt:node-set')">libxslt:node-set() available
</xsl:if>
@@ -77,16 +77,10 @@
</xsl:if>
<xsl:if test="function-available('xt:node-set')">xt:node-set() available
</xsl:if>
-<xsl:if test="function-available('libxslt:evaluate')">libxslt:evaluate() available
-</xsl:if>
<xsl:if test="function-available('saxon:evaluate')">saxon:evaluate() available
</xsl:if>
-<xsl:if test="function-available('libxslt:expression')">libxslt:expression() available
-</xsl:if>
<xsl:if test="function-available('saxon:expression')">saxon:expression() available
</xsl:if>
-<xsl:if test="function-available('libxslt:eval')">libxslt:eval() available
-</xsl:if>
<xsl:if test="function-available('saxon:eval')">saxon:eval() available
</xsl:if>
</xsl:template>