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:
11
ChangeLog
11
ChangeLog
@@ -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
|
||||
|
||||
@@ -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
113
libxslt/documents.c
Normal 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
30
libxslt/documents.h
Normal 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__ */
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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"))) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 */
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user