Skip to content
Snippets Groups Projects
Commit 96ed246c7e7d authored by Daniel Veillard's avatar Daniel Veillard
Browse files

- libxslt/Makefile.am libxslt/template.[ch]: added a template

  specific module. Added attribute value template, at least in
  one spot.
- tests/REC2/Makefile.am tests/REC2/svg.xml: the SVG test from
  the spec now works too.
- libxslt/variables.c: fixed the debug
- libxslt/xslt.c: fixed an ugly uninitialized variable
- libxslt/transform.c: now using attr template processing
Daniel
parent 9f140b4e08ad
No related branches found
No related tags found
No related merge requests found
Sat Jan 20 23:35:07 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* libxslt/Makefile.am libxslt/template.[ch]: added a template
specific module. Added attribute value template, at least in
one spot.
* tests/REC2/Makefile.am tests/REC2/svg.xml: the SVG test from
the spec now works too.
* libxslt/variables.c: fixed the debug
* libxslt/xslt.c: fixed an ugly uninitialized variable
* libxslt/transform.c: now using attr template processing
Sat Jan 20 17:59:20 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* libxslt/transform.c libxslt/variables.[ch] libxslt/xslt.c
......
......@@ -10,6 +10,8 @@
xsltutils.h \
pattern.c \
pattern.h \
templates.c \
templates.h \
variables.c \
variables.h \
transform.c \
......
/*
* templates.c: Implementation of the template processing
*
* Reference:
* http://www.w3.org/TR/1999/REC-xslt-19991116
*
* See Copyright for the status of this software.
*
* Daniel.Veillard@imag.fr
*/
#include "xsltconfig.h"
#include <string.h>
#include <libxml/xmlmemory.h>
#include <libxml/tree.h>
#include <libxml/xmlerror.h>
#include <libxml/xpathInternals.h>
#include <libxml/parserInternals.h>
#include "xslt.h"
#include "xsltInternals.h"
#include "xsltutils.h"
#include "variables.h"
#include "templates.h"
#define DEBUG_TEMPLATES
/************************************************************************
* *
* Module interfaces *
* *
************************************************************************/
/**
* xsltEvalXPathString:
* @ctxt: the XSLT transformation context
* @str: the XPath expression
*
* Process the expression using XPath and get a string
*
* Returns the computed string value or NULL, must be deallocated by the
* caller.
*/
xmlChar *
xsltEvalXPathString(xsltTransformContextPtr ctxt, const xmlChar *expr) {
xmlChar *ret = NULL;
xmlXPathObjectPtr res, tmp;
xmlXPathParserContextPtr xpathParserCtxt;
if (ctxt->xpathCtxt == NULL) {
xmlXPathInit();
ctxt->xpathCtxt = xmlXPathNewContext(ctxt->doc);
if (ctxt->xpathCtxt == NULL)
return(NULL);
XSLT_REGISTER_VARIABLE_LOOKUP(ctxt);
}
xpathParserCtxt =
xmlXPathNewParserContext(expr, ctxt->xpathCtxt);
if (xpathParserCtxt == NULL)
return(NULL);
ctxt->xpathCtxt->node = ctxt->node;
xmlXPathEvalExpr(xpathParserCtxt);
xmlXPathStringFunction(xpathParserCtxt, 1);
res = valuePop(xpathParserCtxt);
do {
tmp = valuePop(xpathParserCtxt);
if (tmp != NULL) {
xmlXPathFreeObject(tmp);
}
} while (tmp != NULL);
if (res != NULL) {
if (res->type == XPATH_STRING) {
ret = res->stringval;
res->stringval = NULL;
} else {
xsltGenericError(xsltGenericErrorContext,
"xpath : string() function didn't returned a String\n");
}
xmlXPathFreeObject(res);
}
xmlXPathFreeParserContext(xpathParserCtxt);
#ifdef DEBUG_TEMPLATES
xsltGenericDebug(xsltGenericDebugContext,
"xsltEvalXPathString: %s returns %s\n", expr, ret);
#endif
return(ret);
}
/**
* xsltAttrTemplateValueProcess:
* @ctxt: the XSLT transformation context
* @str: the attribute template node value
*
* Process the given node and return the new string value.
*
* Returns the computed string value or NULL, must be deallocated by the
* caller.
*/
xmlChar *
xsltAttrTemplateValueProcess(xsltTransformContextPtr ctxt, const xmlChar *str) {
xmlChar *ret = NULL, *ret2;
const xmlChar *cur;
xmlChar *expr, *val;
if (str == NULL) return(NULL);
cur = str;
while (*cur != 0) {
if (*cur == '{') {
ret2 = xmlStrncat(ret, str, cur - str);
if (ret != NULL)
xmlFree(ret);
ret = ret2;
str = cur;
cur++;
while ((*cur != 0) && (*cur != '}')) cur++;
if (*cur == 0) {
ret2 = xmlStrncat(ret, str, cur - str);
xmlFree(ret);
return(ret2);
}
str++;
expr = xmlStrndup(str, cur - str);
if (expr == NULL)
return(ret);
else {
val = xsltEvalXPathString(ctxt, expr);
xmlFree(expr);
if (val != NULL) {
ret2 = xmlStrcat(ret, val);
if (ret != NULL)
xmlFree(ret);
xmlFree(val);
ret = ret2;
}
}
cur++;
str = cur;
} else
cur++;
}
if (cur != str) {
ret2 = xmlStrncat(ret, str, cur - str);
if (ret != NULL)
xmlFree(ret);
ret = ret2;
}
return(ret);
}
/**
* xsltAttrTemplateProcess:
* @ctxt: the XSLT transformation context
* @target: the result node
* @cur: the attribute template node
*
* Process the given attribute and return the new processed copy.
*
* Returns the attribute replacement.
*/
xmlAttrPtr
xsltAttrTemplateProcess(xsltTransformContextPtr ctxt, xmlNodePtr target,
xmlAttrPtr cur) {
xmlAttrPtr ret;
if ((ctxt == NULL) || (cur == NULL))
return(NULL);
if (cur->type != XML_ATTRIBUTE_NODE)
return(NULL);
if ((cur->ns != NULL) &&
(xmlStrEqual(cur->ns->href, XSLT_NAMESPACE))) {
/* TODO: check for replacement namespaces */
return(NULL);
}
ret = xmlNewDocProp(ctxt->output, cur->name, NULL);
if (ret == NULL) return(NULL);
ret->parent = target;
if ((cur->ns != NULL) && (target != NULL)) {
if ((target != NULL) && (target->ns != NULL) &&
(xmlStrEqual(target->ns->href, cur->ns->href))) {
ret->ns = target->ns;
} else {
xmlNsPtr ns;
ns = xmlSearchNsByHref(ctxt->output, target, cur->ns->href);
if (ns != NULL) {
ret->ns = ns;
} else {
ns = xmlNewNs(target, cur->ns->href, cur->ns->prefix);
ret->ns = ns;
}
}
} else
ret->ns = NULL;
if (cur->children != NULL) {
xmlChar *in = xmlNodeListGetString(ctxt->doc, cur->children, 1);
xmlChar *out;
if (in != NULL) {
out = xsltAttrTemplateValueProcess(ctxt, in);
ret->children = xmlNewDocText(ctxt->output, out);
xmlFree(out);
xmlFree(in);
} else
ret->children = NULL;
} else
ret->children = NULL;
return(ret);
}
/**
* xsltAttrListTemplateProcess:
* @ctxt: the XSLT transformation context
* @target: the element where the attributes will be grafted
* @cur: the first attribute
*
* Do a copy of an attribute list with attribute template processing
*
* Returns: a new xmlAttrPtr, or NULL in case of error.
*/
xmlAttrPtr
xsltAttrListTemplateProcess(xsltTransformContextPtr ctxt,
xmlNodePtr target, xmlAttrPtr cur) {
xmlAttrPtr ret = NULL;
xmlAttrPtr p = NULL,q;
while (cur != NULL) {
q = xsltAttrTemplateProcess(ctxt, target, cur);
if (p == NULL) {
ret = p = q;
} else {
p->next = q;
q->prev = p;
p = q;
}
cur = cur->next;
}
return(ret);
}
/**
* xsltTemplateProcess:
* @ctxt: the XSLT transformation context
* @node: the attribute template node
*
* Process the given node and return the new string value.
*
* Returns the computed tree replacement
*/
xmlNodePtr *
xsltTemplateProcess(xsltTransformContextPtr ctxt, xmlNodePtr node) {
if (node == NULL)
return(NULL);
return(0);
}
/*
* templates.h: interface for the template processing
*
* See Copyright for the status of this software.
*
* Daniel.Veillard@imag.fr
*/
#ifndef __XML_XSLT_TEMPLATES_H__
#define __XML_XSLT_TEMPLATES_H__
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include "xsltInternals.h"
#ifdef __cplusplus
extern "C" {
#endif
xmlChar * xsltEvalXPathString (xsltTransformContextPtr ctxt,
const xmlChar *expr);
xmlNodePtr * xsltTemplateProcess (xsltTransformContextPtr ctxt,
xmlNodePtr node);
xmlAttrPtr xsltAttrListTemplateProcess (xsltTransformContextPtr ctxt,
xmlNodePtr target,
xmlAttrPtr cur);
xmlAttrPtr xsltAttrTemplateProcess (xsltTransformContextPtr ctxt,
xmlNodePtr target,
xmlAttrPtr attr);
xmlChar * xsltAttrTemplateValueProcess (xsltTransformContextPtr ctxt,
const xmlChar* attr);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_TEMPLATES_H__ */
......@@ -30,6 +30,7 @@
#include "pattern.h"
#include "transform.h"
#include "variables.h"
#include "templates.h"
#define DEBUG_PROCESS
......@@ -839,7 +840,8 @@
* TODO: Do the substitution of {} XPath expressions !!!
*/
if (cur->properties != NULL)
copy->properties = xmlCopyPropList(copy, cur->properties);
copy->properties = xsltAttrListTemplateProcess(ctxt,
copy, cur->properties);
}
/*
......
......@@ -25,7 +25,7 @@
#include "xsltutils.h"
#include "variables.h"
#define DEBUG_VARIABLES
#define DEBUG_VARIABLE
/*
* Types are private:
......@@ -293,6 +293,10 @@
if (name == NULL)
return(-1);
#ifdef DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
"Defineing variable %s\n", name);
#endif
elem = xsltNewStackElem();
if (elem == NULL)
return(-1);
......@@ -310,6 +314,7 @@
ctxt->xpathCtxt);
if (xpathParserCtxt == NULL)
goto error;
ctxt->xpathCtxt->node = ctxt->node;
xmlXPathEvalExpr(xpathParserCtxt);
result = valuePop(xpathParserCtxt);
do {
......@@ -369,6 +374,5 @@
#endif
TODO /* Variable value computation needed */
}
error:
if (elem->value != NULL)
return(xmlXPathObjectCopy(elem->value));
......@@ -373,5 +377,9 @@
if (elem->value != NULL)
return(xmlXPathObjectCopy(elem->value));
#ifdef DEBUG_VARIABLE
xsltGenericDebug(xsltGenericDebugContext,
"variable not found %s\n", name);
#endif
return(NULL);
}
......@@ -426,7 +434,6 @@
}
#ifdef DEBUG_VARIABLE
if (ret != NULL)
xsltGenericDebug(xsltGenericDebugContext,
"Parsing variable %s\n", name);
#endif
......
......@@ -713,7 +713,7 @@
if (top == NULL)
return;
prop = xmlGetNsProp(cur, (const xmlChar *)"version", XSLT_NAMESPACE);
prop = xmlGetNsProp(top, (const xmlChar *)"version", XSLT_NAMESPACE);
if (prop == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsl:version is missing: document may not be a stylesheet\n");
......
......@@ -8,6 +8,10 @@
@($(top_builddir)/libxslt/xsltproc vrml.xsl data.xml > vrml.res ; \
diff vrml.xml vrml.res ; \
grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\
rm -f doc.res)
rm -f vrml.res)
@($(top_builddir)/libxslt/xsltproc svg.xsl data.xml > svg.res ; \
diff svg.xml svg.res ; \
grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\
rm -f svg.res)
<svg width="3in" height="3in"
xmlns="http://www.w3.org/Graphics/SVG/svg-19990412.dtd">
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/Graphics/SVG/SVG-19990812.dtd" width="3in" height="3in">
<g style="stroke: #000000">
<line x1="0" x2="150" y1="150" y2="150"/>
<line x1="0" x2="0" y1="0" y2="150"/>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment