mirror of
https://gitlab.gnome.org/GNOME/libxslt
synced 2025-11-06 23:49:25 +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:
12
ChangeLog
12
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>
|
Sun Oct 7 13:15:33 CEST 2001 Daniel Veillard <daniel@veillard.com>
|
||||||
|
|
||||||
* libxslt/numbers.c: fixed bug #61070, number ANY formatting
|
* libxslt/numbers.c: fixed bug #61070, number ANY formatting
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ libexslt_la_SOURCES = \
|
|||||||
sets.c \
|
sets.c \
|
||||||
functions.c \
|
functions.c \
|
||||||
strings.c \
|
strings.c \
|
||||||
date.c
|
date.c \
|
||||||
|
saxon.c
|
||||||
|
|
||||||
libexslt_la_LIBADD = $(EXTRA_LIBS)
|
libexslt_la_LIBADD = $(EXTRA_LIBS)
|
||||||
libexslt_la_LDFLAGS = -version-info @LIBEXSLT_VERSION_INFO@
|
libexslt_la_LDFLAGS = -version-info @LIBEXSLT_VERSION_INFO@
|
||||||
|
|||||||
@@ -28,5 +28,6 @@ exsltRegisterAll (void) {
|
|||||||
exsltFuncRegister();
|
exsltFuncRegister();
|
||||||
exsltStrRegister();
|
exsltStrRegister();
|
||||||
exsltDateRegister();
|
exsltDateRegister();
|
||||||
|
exsltSaxonRegister();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ LIBEXSLT_PUBLIC extern const int exsltLibxmlVersion;
|
|||||||
#define EXSLT_FUNCTIONS_NAMESPACE ((const xmlChar *) "http://exslt.org/functions")
|
#define EXSLT_FUNCTIONS_NAMESPACE ((const xmlChar *) "http://exslt.org/functions")
|
||||||
#define EXSLT_STRINGS_NAMESPACE ((const xmlChar *) "http://exslt.org/strings")
|
#define EXSLT_STRINGS_NAMESPACE ((const xmlChar *) "http://exslt.org/strings")
|
||||||
#define EXSLT_DATE_NAMESPACE ((const xmlChar *) "http://exslt.org/dates-and-times")
|
#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 exsltCommonRegister (void);
|
||||||
void exsltMathRegister (void);
|
void exsltMathRegister (void);
|
||||||
@@ -23,6 +24,7 @@ void exsltSetsRegister (void);
|
|||||||
void exsltFuncRegister (void);
|
void exsltFuncRegister (void);
|
||||||
void exsltStrRegister (void);
|
void exsltStrRegister (void);
|
||||||
void exsltDateRegister (void);
|
void exsltDateRegister (void);
|
||||||
|
void exsltSaxonRegister (void);
|
||||||
|
|
||||||
void exsltRegisterAll (void);
|
void exsltRegisterAll (void);
|
||||||
|
|
||||||
|
|||||||
186
libexslt/saxon.c
Normal file
186
libexslt/saxon.c
Normal 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);
|
||||||
|
}
|
||||||
@@ -5,5 +5,5 @@
|
|||||||
boolean;
|
boolean;
|
||||||
node-set;
|
node-set;
|
||||||
RTF;
|
RTF;
|
||||||
;
|
external;
|
||||||
</out>
|
</out>
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
<?xml version='1.0'?>
|
<?xml version='1.0'?>
|
||||||
<xsl:stylesheet
|
<xsl:stylesheet
|
||||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
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'>
|
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:template match="/">
|
||||||
<xsl:variable name="string">doc/one</xsl:variable>
|
<xsl:variable name="string">doc/one</xsl:variable>
|
||||||
<xsl:value-of select="libxslt:evaluate($string)"/>
|
<xsl:value-of select="saxon:evaluate($string)"/>
|
||||||
<xsl:value-of select="count(libxslt:evaluate('/doc/one')/../*)"/>
|
<xsl:value-of select="count(saxon:evaluate('/doc/one')/../*)"/>
|
||||||
<xsl:value-of select="libxslt:evaluate(/doc/three)"/>
|
<xsl:value-of select="saxon:evaluate(/doc/three)"/>
|
||||||
<xsl:value-of select="libxslt:eval($expression)"/>
|
<xsl:value-of select="saxon:eval($expression)"/>
|
||||||
<xsl:apply-templates/>
|
<xsl:apply-templates/>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="four">
|
<xsl:template match="four">
|
||||||
<xsl:variable name="string">doc/one</xsl:variable>
|
<xsl:variable name="string">doc/one</xsl:variable>
|
||||||
<xsl:value-of select="libxslt:evaluate($string)"/>
|
<xsl:value-of select="saxon:evaluate($string)"/>
|
||||||
<xsl:value-of select="libxslt:eval($expression)"/>
|
<xsl:value-of select="saxon:eval($expression)"/>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="text()"/>
|
<xsl:template match="text()"/>
|
||||||
|
|||||||
@@ -30,14 +30,11 @@ saxon:output available
|
|||||||
xalanredirect:write available
|
xalanredirect:write available
|
||||||
xt:document available
|
xt:document available
|
||||||
libxslt:debug available
|
libxslt:debug available
|
||||||
=== 9 Extension functions:
|
=== 6 Extension functions:
|
||||||
libxslt:node-set() available
|
libxslt:node-set() available
|
||||||
saxon:node-set() available
|
saxon:node-set() available
|
||||||
xt:node-set() available
|
xt:node-set() available
|
||||||
libxslt:evaluate() available
|
|
||||||
saxon:evaluate() available
|
saxon:evaluate() available
|
||||||
libxslt:expression() available
|
|
||||||
saxon:expression() available
|
saxon:expression() available
|
||||||
libxslt:eval() available
|
|
||||||
saxon:eval() available
|
saxon:eval() available
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
</xsl:if>
|
</xsl:if>
|
||||||
<xsl:if test="element-available('libxslt:debug')">libxslt:debug available
|
<xsl:if test="element-available('libxslt:debug')">libxslt:debug available
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
<xsl:text> === 9 Extension functions:
|
<xsl:text> === 6 Extension functions:
|
||||||
</xsl:text>
|
</xsl:text>
|
||||||
<xsl:if test="function-available('libxslt:node-set')">libxslt:node-set() available
|
<xsl:if test="function-available('libxslt:node-set')">libxslt:node-set() available
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
@@ -77,16 +77,10 @@
|
|||||||
</xsl:if>
|
</xsl:if>
|
||||||
<xsl:if test="function-available('xt:node-set')">xt:node-set() available
|
<xsl:if test="function-available('xt:node-set')">xt:node-set() available
|
||||||
</xsl:if>
|
</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 test="function-available('saxon:evaluate')">saxon:evaluate() available
|
||||||
</xsl:if>
|
</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 test="function-available('saxon:expression')">saxon:expression() available
|
||||||
</xsl:if>
|
</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 test="function-available('saxon:eval')">saxon:eval() available
|
||||||
</xsl:if>
|
</xsl:if>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|||||||
Reference in New Issue
Block a user