1
0
mirror of https://gitlab.gnome.org/GNOME/libxslt synced 2025-11-08 11:02:18 +03:00

Messing with document related structures, keys, etc ...:

- libxslt/Makefile.am libxslt/documents.[ch]: added a new module
  to deal with documents
- libxslt/functions.c: fixed document() to return the same set
  for teh same URL
- libxslt/keys.[ch] libxslt/templates.c libxslt/transform.c
  libxslt/variables.c libxslt/xsltInternals.h: keys are really
  associated to loaded documents, not to the transformation
  context, made the change, this impacted a number of modules
Daniel
This commit is contained in:
Daniel Veillard
2001-02-09 14:52:32 +00:00
parent cb8dce6e56
commit 9700cf32b2
11 changed files with 239 additions and 65 deletions

View File

@@ -1,3 +1,14 @@
Fri Feb 9 15:49:19 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* libxslt/Makefile.am libxslt/documents.[ch]: added a new module
to deal with documents
* libxslt/functions.c: fixed document() to return the same set
for teh same URL
* libxslt/keys.[ch] libxslt/templates.c libxslt/transform.c
libxslt/variables.c libxslt/xsltInternals.h: keys are really
associated to loaded documents, not to the transformation
context, made the change, this impacted a number of modules
Thu Feb 8 12:51:00 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* doc/libxslt.sgml doc/html/*.html: updated and rebuilt the doc list

View File

@@ -17,6 +17,7 @@ xsltinc_HEADERS = \
namespaces.h \
imports.h \
attributes.h \
documents.h \
transform.h \
xsltInternals.h
@@ -32,6 +33,7 @@ libxslt_la_SOURCES = \
namespaces.c \
imports.c \
attributes.c \
documents.c \
transform.c

113
libxslt/documents.c Normal file
View File

@@ -0,0 +1,113 @@
/*
* documents.c: Implementation of the documents handling
*
* 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/hash.h>
#include "xslt.h"
#include "xsltInternals.h"
#include "xsltutils.h"
#include "documents.h"
#include "keys.h"
#define DEBUG_DOCUMENTS
/************************************************************************
* *
* Module interfaces *
* *
************************************************************************/
/**
* xsltNewDocument:
* @ctxt: an XSLT transformation context
* @doc: a parsed XML document
*
* Register a new document, apply key computations
*/
xsltDocumentPtr
xsltNewDocument(xsltTransformContextPtr ctxt, xmlDocPtr doc) {
xsltDocumentPtr cur;
cur = (xsltDocumentPtr) xmlMalloc(sizeof(xsltDocument));
if (cur == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltNewDocument : malloc failed\n");
return(NULL);
}
memset(cur, 0, sizeof(xsltDocument));
cur->doc = doc;
cur->next = ctxt->docList;
ctxt->docList = cur;
xsltInitCtxtKeys(ctxt, cur);
return(cur);
}
/**
* xsltFreeDocuments:
* @ctxt: an XSLT transformation context
*
* Free up all the space used by the loaded documents
*/
void
xsltFreeDocuments(xsltTransformContextPtr ctxt) {
xsltDocumentPtr doc, cur;
cur = ctxt->document;
while (cur != NULL) {
doc = cur;
cur = cur->next;
xsltFreeDocumentKeys(doc);
if (!doc->main)
xmlFreeDoc(doc->doc);
xmlFree(doc);
}
}
/**
* xsltLoadDocument:
* @ctxt: an XSLT transformation context
* @URI: the computed URI of the document
*
* Try to load a document within the XSLT transformation context
*
* Returns the new xsltDocumentPtr or NULL in case of error
*/
xsltDocumentPtr
xsltLoadDocument(xsltTransformContextPtr ctxt, const xmlChar *URI) {
xsltDocumentPtr ret;
xmlDocPtr doc;
if ((ctxt == NULL) || (URI == NULL))
return(NULL);
/*
* Walk the context list to find the document if preparsed
*/
ret = ctxt->docList;
while (ret != NULL) {
if ((ret->doc != NULL) && (ret->doc->URL != NULL) &&
(xmlStrEqual(ret->doc->URL, URI)))
return(ret);
ret = ret->next;
}
doc = xmlParseFile((const char *) URI);
if (doc == NULL)
return(NULL);
ret = xsltNewDocument(ctxt, doc);
return(ret);
}

30
libxslt/documents.h Normal file
View File

@@ -0,0 +1,30 @@
/*
* document.h: interface for the document handling
*
* See Copyright for the status of this software.
*
* Daniel.Veillard@imag.fr
*/
#ifndef __XML_XSLT_DOCUMENTS_H__
#define __XML_XSLT_DOCUMENTS_H__
#include <libxml/tree.h>
#include "xsltInternals.h"
#ifdef __cplusplus
extern "C" {
#endif
xsltDocumentPtr xsltNewDocument (xsltTransformContextPtr ctxt,
xmlDocPtr doc);
xsltDocumentPtr xsltLoadDocument (xsltTransformContextPtr ctxt,
const xmlChar *URI);
void xsltFreeDocuments (xsltTransformContextPtr ctxt);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_DOCUMENTS_H__ */

View File

@@ -37,6 +37,7 @@
#include "functions.h"
#include "numbersInternals.h"
#include "keys.h"
#include "documents.h"
#define DEBUG_FUNCTION
@@ -57,7 +58,7 @@
*/
void
xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs){
xmlDocPtr doc;
xsltDocumentPtr doc;
xmlXPathObjectPtr obj;
xmlChar *base, *URI;
@@ -101,31 +102,21 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs){
if (URI == NULL) {
valuePush(ctxt, xmlXPathNewNodeSet(NULL));
} else {
doc = xmlParseDoc(URI);
if (doc == NULL)
valuePush(ctxt, xmlXPathNewNodeSet(NULL));
else {
xsltTransformContextPtr tctxt;
xsltTransformContextPtr tctxt;
/*
* link it to the context for cleanup when done
*/
tctxt = (xsltTransformContextPtr) ctxt->context->extra;
if (tctxt == NULL) {
xsltGenericError(xsltGenericErrorContext,
tctxt = (xsltTransformContextPtr) ctxt->context->extra;
if (tctxt == NULL) {
xsltGenericError(xsltGenericErrorContext,
"document() : internal error tctxt == NULL\n");
xmlFreeDoc(doc);
valuePush(ctxt, xmlXPathNewNodeSet(NULL));
} else {
doc = xsltLoadDocument(tctxt, URI);
if (doc == NULL)
valuePush(ctxt, xmlXPathNewNodeSet(NULL));
} else {
/*
* Keep a link from the context to be able to deallocate
*/
doc->next = (xmlNodePtr) tctxt->extraDocs;
tctxt->extraDocs = doc;
else {
/* TODO: use XPointer of HTML location for fragment ID */
/* pbm #xxx can lead to location sets, not nodesets :-) */
valuePush(ctxt, xmlXPathNewNodeSet((xmlNodePtr) doc));
valuePush(ctxt, xmlXPathNewNodeSet((xmlNodePtr) doc->doc));
}
}
}

View File

@@ -263,7 +263,7 @@ xsltGetKey(xsltTransformContextPtr ctxt, const xmlChar *name,
"Get key %s, value %s\n", name, value);
#endif
table = (xsltKeyTablePtr) ctxt->keys;
table = (xsltKeyTablePtr) ctxt->document->keys;
while (table != NULL) {
if (xmlStrEqual(table->name, name) &&
(((nameURI == NULL) && (table->nameURI == NULL)) ||
@@ -280,12 +280,14 @@ xsltGetKey(xsltTransformContextPtr ctxt, const xmlChar *name,
/**
* xsltInitCtxtKey:
* @ctxt: an XSLT transformation context
* @doc: an XSLT document
* @keyd: the key definition
*
* Computes the key tables this key and for the current input document.
*/
void
xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltKeyDefPtr keyd) {
xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr doc,
xsltKeyDefPtr keyd) {
int i;
xmlChar *pattern = NULL;
xmlNodeSetPtr nodelist = NULL, keylist;
@@ -312,8 +314,9 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltKeyDefPtr keyd) {
xmlXPathNewParserContext(pattern, ctxt->xpathCtxt);
if (xpathParserCtxt == NULL)
goto error;
ctxt->node = (xmlNodePtr) ctxt->doc;
ctxt->xpathCtxt->node = (xmlNodePtr) ctxt->doc;
ctxt->document = doc;
ctxt->node = (xmlNodePtr) doc->doc;
ctxt->xpathCtxt->node = (xmlNodePtr) doc->doc;
xmlXPathEvalExpr(xpathParserCtxt);
res = valuePop(xpathParserCtxt);
do {
@@ -382,8 +385,8 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltKeyDefPtr keyd) {
}
}
table->next = ctxt->keys;
ctxt->keys = table;
table->next = doc->keys;
doc->keys = table;
error:
if (res != NULL)
@@ -396,23 +399,28 @@ error:
/**
* xsltInitCtxtKeys:
* @ctxt: an XSLT transformation context
* @ctxt: an XSLT transformation context
* @doc: an XSLT document
*
* Computes all the keys tables for the current input document.
* Should be done before global varibales are initialized.
*/
void
xsltInitCtxtKeys(xsltTransformContextPtr ctxt) {
xsltInitCtxtKeys(xsltTransformContextPtr ctxt, xsltDocumentPtr doc) {
xsltStylesheetPtr style;
xsltKeyDefPtr keyd;
if (ctxt == NULL)
if ((ctxt == NULL) || (doc == NULL))
return;
#ifdef DEBUG_KEYS
xsltGenericDebug(xsltGenericDebugContext, "Initializing keys on %s\n",
doc->doc->URL);
#endif
style = ctxt->style;
while (style != NULL) {
keyd = (xsltKeyDefPtr) style->keys;
while (keyd != NULL) {
xsltInitCtxtKey(ctxt, keyd);
xsltInitCtxtKey(ctxt, doc, keyd);
keyd = keyd->next;
}
@@ -421,18 +429,6 @@ xsltInitCtxtKeys(xsltTransformContextPtr ctxt) {
}
}
/**
* xsltFreeCtxtKeys:
* @ctxt: an XSLT transformation context
*
* Free up all the space used by the key tables
*/
void
xsltFreeCtxtKeys(xsltTransformContextPtr ctxt) {
if (ctxt->keys)
xsltFreeKeyTableList((xsltKeyTablePtr) ctxt->keys);
}
/*
* xsltIsKey:
* @ctxt: an XSLT transformation context
@@ -454,3 +450,16 @@ xsltIsKey(xsltTransformContextPtr ctxt, xmlNodePtr node) {
return(1);
return(0);
}
/*
* xsltFreeDocumentKeys:
* @doc: a XSLT document
*
* Free the keys associated to a document
*/
void
xsltFreeDocumentKeys(xsltDocumentPtr doc) {
if (doc != NULL)
xsltFreeKeyTableList(doc->keys);
}

View File

@@ -25,9 +25,11 @@ xmlNodeSetPtr xsltGetKey (xsltTransformContextPtr ctxt,
const xmlChar *name,
const xmlChar *nameURI,
const xmlChar *value);
void xsltInitCtxtKeys (xsltTransformContextPtr ctxt);
void xsltInitCtxtKeys (xsltTransformContextPtr ctxt,
xsltDocumentPtr doc);
void xsltFreeKeys (xsltStylesheetPtr style);
void xsltFreeCtxtKeys (xsltTransformContextPtr ctxt);
void xsltFreeDocumentKeys (xsltDocumentPtr doc);
#ifdef __cplusplus
}
#endif

View File

@@ -291,7 +291,7 @@ xsltAttrTemplateProcess(xsltTransformContextPtr ctxt, xmlNodePtr target,
if (xmlStrEqual(cur->name, (const xmlChar *)"use-attribute-sets")) {
xmlChar *in;
in = xmlNodeListGetString(ctxt->doc, cur->children, 1);
in = xmlNodeListGetString(ctxt->document->doc, cur->children, 1);
if (in != NULL) {
xsltApplyAttributeSet(ctxt, ctxt->node, NULL, in);
xmlFree(in);
@@ -309,7 +309,8 @@ xsltAttrTemplateProcess(xsltTransformContextPtr ctxt, xmlNodePtr target,
ret->ns = NULL;
if (cur->children != NULL) {
xmlChar *in = xmlNodeListGetString(ctxt->doc, cur->children, 1);
xmlChar *in = xmlNodeListGetString(ctxt->document->doc,
cur->children, 1);
xmlChar *out;
/* TODO: optimize if no template value was detected */

View File

@@ -36,6 +36,7 @@
#include "templates.h"
#include "imports.h"
#include "keys.h"
#include "documents.h"
#define DEBUG_PROCESS
@@ -60,6 +61,7 @@
/**
* xsltNewTransformContext:
* @style: a parsed XSLT stylesheet
* @doc: the input document
*
* Create a new XSLT TransformContext
@@ -67,8 +69,9 @@
* Returns the newly allocated xsltTransformContextPtr or NULL in case of error
*/
xsltTransformContextPtr
xsltNewTransformContext(xmlDocPtr doc) {
xsltNewTransformContext(xsltStylesheetPtr style, xmlDocPtr doc) {
xsltTransformContextPtr cur;
xsltDocumentPtr docu;
cur = (xsltTransformContextPtr) xmlMalloc(sizeof(xsltTransformContext));
if (cur == NULL) {
@@ -77,8 +80,8 @@ xsltNewTransformContext(xmlDocPtr doc) {
return(NULL);
}
memset(cur, 0, sizeof(xsltTransformContext));
cur->style = style;
xmlXPathInit();
cur->doc = doc;
cur->xpathCtxt = xmlXPathNewContext(doc);
if (cur->xpathCtxt == NULL) {
xsltGenericError(xsltGenericErrorContext,
@@ -87,6 +90,15 @@ xsltNewTransformContext(xmlDocPtr doc) {
return(NULL);
}
XSLT_REGISTER_VARIABLE_LOOKUP(cur);
docu = xsltNewDocument(cur, doc);
if (docu == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltNewTransformContext : xsltNewDocument failed\n");
xmlFree(cur);
return(NULL);
}
docu->main = 1;
cur->document = docu;
return(cur);
}
@@ -98,20 +110,12 @@ xsltNewTransformContext(xmlDocPtr doc) {
*/
void
xsltFreeTransformContext(xsltTransformContextPtr ctxt) {
xmlDocPtr doc, next;
if (ctxt == NULL)
return;
doc = ctxt->extraDocs;
while (doc != NULL) {
next = (xmlDocPtr) doc->next;
xmlFreeDoc(doc);
doc = next;
}
if (ctxt->xpathCtxt != NULL)
xmlXPathFreeContext(ctxt->xpathCtxt);
xsltFreeVariableHashes(ctxt);
xsltFreeCtxtKeys(ctxt);
xsltFreeDocuments(ctxt);
memset(ctxt, -1, sizeof(xsltTransformContext));
xmlFree(ctxt);
}
@@ -1983,11 +1987,9 @@ xsltApplyStylesheet(xsltStylesheetPtr style, xmlDocPtr doc) {
if ((style == NULL) || (doc == NULL))
return(NULL);
ctxt = xsltNewTransformContext(doc);
ctxt = xsltNewTransformContext(style, doc);
if (ctxt == NULL)
return(NULL);
ctxt->style = style;
xsltInitCtxtKeys(ctxt);
xsltEvalGlobalVariables(ctxt);
if ((style->method != NULL) &&
(!xmlStrEqual(style->method, (const xmlChar *) "xml"))) {

View File

@@ -379,7 +379,7 @@ xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
xsltGenericDebug(xsltGenericDebugContext,
"Evaluating global variables\n");
#endif
ctxt->node = (xmlNodePtr) ctxt->doc;
ctxt->node = (xmlNodePtr) ctxt->document->doc;
style = ctxt->style;
/* TODO: handle the stylesheet cascade */
if (style != NULL) {

View File

@@ -158,6 +158,19 @@ struct _xsltStylesheet {
};
/*
* Data structure associated to a document
*/
typedef struct _xsltDocument xsltDocument;
typedef xsltDocument *xsltDocumentPtr;
struct _xsltDocument {
struct _xsltDocument *next; /* documents are kept in a chained list */
int main; /* is this the main document */
xmlDocPtr doc; /* the parsed document */
void *keys; /* key tables storage */
};
/*
* The in-memory structure corresponding to an XSLT Transformation
*/
@@ -182,7 +195,9 @@ struct _xsltTransformContext {
const xmlChar *mode; /* the current mode */
const xmlChar *modeURI; /* the current mode URI */
xmlDocPtr doc; /* the current doc */
xsltDocumentPtr docList; /* the document list */
xsltDocumentPtr document; /* the current document */
xmlNodePtr node; /* the current node */
xmlNodeSetPtr nodeList; /* the current node list */
@@ -192,8 +207,6 @@ struct _xsltTransformContext {
xmlXPathContextPtr xpathCtxt; /* the XPath context */
void *variablesHash; /* hash table or wherever variables
informations are stored */
void *keys; /* key tables storage */
xmlDocPtr extraDocs; /* extra docs parsed by document() */
xsltTransformState state; /* the current state */
};