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> 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 * doc/libxslt.sgml doc/html/*.html: updated and rebuilt the doc list

View File

@@ -17,6 +17,7 @@ xsltinc_HEADERS = \
namespaces.h \ namespaces.h \
imports.h \ imports.h \
attributes.h \ attributes.h \
documents.h \
transform.h \ transform.h \
xsltInternals.h xsltInternals.h
@@ -32,6 +33,7 @@ libxslt_la_SOURCES = \
namespaces.c \ namespaces.c \
imports.c \ imports.c \
attributes.c \ attributes.c \
documents.c \
transform.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 "functions.h"
#include "numbersInternals.h" #include "numbersInternals.h"
#include "keys.h" #include "keys.h"
#include "documents.h"
#define DEBUG_FUNCTION #define DEBUG_FUNCTION
@@ -57,7 +58,7 @@
*/ */
void void
xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs){ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs){
xmlDocPtr doc; xsltDocumentPtr doc;
xmlXPathObjectPtr obj; xmlXPathObjectPtr obj;
xmlChar *base, *URI; xmlChar *base, *URI;
@@ -101,31 +102,21 @@ xsltDocumentFunction(xmlXPathParserContextPtr ctxt, int nargs){
if (URI == NULL) { if (URI == NULL) {
valuePush(ctxt, xmlXPathNewNodeSet(NULL)); valuePush(ctxt, xmlXPathNewNodeSet(NULL));
} else { } else {
doc = xmlParseDoc(URI); xsltTransformContextPtr tctxt;
if (doc == NULL)
valuePush(ctxt, xmlXPathNewNodeSet(NULL));
else {
xsltTransformContextPtr tctxt;
/* tctxt = (xsltTransformContextPtr) ctxt->context->extra;
* link it to the context for cleanup when done if (tctxt == NULL) {
*/ xsltGenericError(xsltGenericErrorContext,
tctxt = (xsltTransformContextPtr) ctxt->context->extra;
if (tctxt == NULL) {
xsltGenericError(xsltGenericErrorContext,
"document() : internal error tctxt == NULL\n"); "document() : internal error tctxt == NULL\n");
xmlFreeDoc(doc); valuePush(ctxt, xmlXPathNewNodeSet(NULL));
} else {
doc = xsltLoadDocument(tctxt, URI);
if (doc == NULL)
valuePush(ctxt, xmlXPathNewNodeSet(NULL)); valuePush(ctxt, xmlXPathNewNodeSet(NULL));
} else { else {
/*
* Keep a link from the context to be able to deallocate
*/
doc->next = (xmlNodePtr) tctxt->extraDocs;
tctxt->extraDocs = doc;
/* TODO: use XPointer of HTML location for fragment ID */ /* TODO: use XPointer of HTML location for fragment ID */
/* pbm #xxx can lead to location sets, not nodesets :-) */ /* 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); "Get key %s, value %s\n", name, value);
#endif #endif
table = (xsltKeyTablePtr) ctxt->keys; table = (xsltKeyTablePtr) ctxt->document->keys;
while (table != NULL) { while (table != NULL) {
if (xmlStrEqual(table->name, name) && if (xmlStrEqual(table->name, name) &&
(((nameURI == NULL) && (table->nameURI == NULL)) || (((nameURI == NULL) && (table->nameURI == NULL)) ||
@@ -280,12 +280,14 @@ xsltGetKey(xsltTransformContextPtr ctxt, const xmlChar *name,
/** /**
* xsltInitCtxtKey: * xsltInitCtxtKey:
* @ctxt: an XSLT transformation context * @ctxt: an XSLT transformation context
* @doc: an XSLT document
* @keyd: the key definition * @keyd: the key definition
* *
* Computes the key tables this key and for the current input document. * Computes the key tables this key and for the current input document.
*/ */
void void
xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltKeyDefPtr keyd) { xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr doc,
xsltKeyDefPtr keyd) {
int i; int i;
xmlChar *pattern = NULL; xmlChar *pattern = NULL;
xmlNodeSetPtr nodelist = NULL, keylist; xmlNodeSetPtr nodelist = NULL, keylist;
@@ -312,8 +314,9 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltKeyDefPtr keyd) {
xmlXPathNewParserContext(pattern, ctxt->xpathCtxt); xmlXPathNewParserContext(pattern, ctxt->xpathCtxt);
if (xpathParserCtxt == NULL) if (xpathParserCtxt == NULL)
goto error; goto error;
ctxt->node = (xmlNodePtr) ctxt->doc; ctxt->document = doc;
ctxt->xpathCtxt->node = (xmlNodePtr) ctxt->doc; ctxt->node = (xmlNodePtr) doc->doc;
ctxt->xpathCtxt->node = (xmlNodePtr) doc->doc;
xmlXPathEvalExpr(xpathParserCtxt); xmlXPathEvalExpr(xpathParserCtxt);
res = valuePop(xpathParserCtxt); res = valuePop(xpathParserCtxt);
do { do {
@@ -382,8 +385,8 @@ xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltKeyDefPtr keyd) {
} }
} }
table->next = ctxt->keys; table->next = doc->keys;
ctxt->keys = table; doc->keys = table;
error: error:
if (res != NULL) if (res != NULL)
@@ -396,23 +399,28 @@ error:
/** /**
* xsltInitCtxtKeys: * 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. * Computes all the keys tables for the current input document.
* Should be done before global varibales are initialized. * Should be done before global varibales are initialized.
*/ */
void void
xsltInitCtxtKeys(xsltTransformContextPtr ctxt) { xsltInitCtxtKeys(xsltTransformContextPtr ctxt, xsltDocumentPtr doc) {
xsltStylesheetPtr style; xsltStylesheetPtr style;
xsltKeyDefPtr keyd; xsltKeyDefPtr keyd;
if (ctxt == NULL) if ((ctxt == NULL) || (doc == NULL))
return; return;
#ifdef DEBUG_KEYS
xsltGenericDebug(xsltGenericDebugContext, "Initializing keys on %s\n",
doc->doc->URL);
#endif
style = ctxt->style; style = ctxt->style;
while (style != NULL) { while (style != NULL) {
keyd = (xsltKeyDefPtr) style->keys; keyd = (xsltKeyDefPtr) style->keys;
while (keyd != NULL) { while (keyd != NULL) {
xsltInitCtxtKey(ctxt, keyd); xsltInitCtxtKey(ctxt, doc, keyd);
keyd = keyd->next; 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: * xsltIsKey:
* @ctxt: an XSLT transformation context * @ctxt: an XSLT transformation context
@@ -454,3 +450,16 @@ xsltIsKey(xsltTransformContextPtr ctxt, xmlNodePtr node) {
return(1); return(1);
return(0); 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 *name,
const xmlChar *nameURI, const xmlChar *nameURI,
const xmlChar *value); const xmlChar *value);
void xsltInitCtxtKeys (xsltTransformContextPtr ctxt); void xsltInitCtxtKeys (xsltTransformContextPtr ctxt,
xsltDocumentPtr doc);
void xsltFreeKeys (xsltStylesheetPtr style); void xsltFreeKeys (xsltStylesheetPtr style);
void xsltFreeCtxtKeys (xsltTransformContextPtr ctxt); void xsltFreeDocumentKeys (xsltDocumentPtr doc);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

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

View File

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

View File

@@ -379,7 +379,7 @@ xsltEvalGlobalVariables(xsltTransformContextPtr ctxt) {
xsltGenericDebug(xsltGenericDebugContext, xsltGenericDebug(xsltGenericDebugContext,
"Evaluating global variables\n"); "Evaluating global variables\n");
#endif #endif
ctxt->node = (xmlNodePtr) ctxt->doc; ctxt->node = (xmlNodePtr) ctxt->document->doc;
style = ctxt->style; style = ctxt->style;
/* TODO: handle the stylesheet cascade */ /* TODO: handle the stylesheet cascade */
if (style != NULL) { 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 * The in-memory structure corresponding to an XSLT Transformation
*/ */
@@ -182,7 +195,9 @@ struct _xsltTransformContext {
const xmlChar *mode; /* the current mode */ const xmlChar *mode; /* the current mode */
const xmlChar *modeURI; /* the current mode URI */ 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 */ xmlNodePtr node; /* the current node */
xmlNodeSetPtr nodeList; /* the current node list */ xmlNodeSetPtr nodeList; /* the current node list */
@@ -192,8 +207,6 @@ struct _xsltTransformContext {
xmlXPathContextPtr xpathCtxt; /* the XPath context */ xmlXPathContextPtr xpathCtxt; /* the XPath context */
void *variablesHash; /* hash table or wherever variables void *variablesHash; /* hash table or wherever variables
informations are stored */ informations are stored */
void *keys; /* key tables storage */
xmlDocPtr extraDocs; /* extra docs parsed by document() */
xsltTransformState state; /* the current state */ xsltTransformState state; /* the current state */
}; };