1
0
mirror of https://gitlab.gnome.org/GNOME/libxslt synced 2025-11-05 12:10:38 +03:00

added implementation of SAXON expression(), eval() and evaluate()

* 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
This commit is contained in:
Thomas Broyer
2001-10-07 16:55:36 +00:00
parent ae7c300b67
commit 3ee2cad5b4
9 changed files with 214 additions and 21 deletions

View File

@@ -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

View File

@@ -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@

View File

@@ -28,5 +28,6 @@ exsltRegisterAll (void) {
exsltFuncRegister();
exsltStrRegister();
exsltDateRegister();
exsltSaxonRegister();
}

View File

@@ -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);

186
libexslt/saxon.c Normal file
View File

@@ -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);
}

View File

@@ -5,5 +5,5 @@
boolean;
node-set;
RTF;
;
external;
</out>

View File

@@ -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()"/>

View File

@@ -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

View File

@@ -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>