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

I generate a root node, I assume it's significant progress !

* libxslt/transform.[ch] Makefile.am: started adding the
  transformation module
* pattern.[ch] xslt.c: more work...
Daniel
This commit is contained in:
Daniel Veillard
2001-01-11 20:13:26 +00:00
parent 9264e233eb
commit 2d430b16ee
8 changed files with 353 additions and 5 deletions

View File

@@ -1,3 +1,9 @@
Thu Jan 11 21:10:59 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* libxslt/transform.[ch] Makefile.am: started adding the
transformation module
* pattern.[ch] xslt.c: more work...
Thu Jan 11 14:02:03 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr> Thu Jan 11 14:02:03 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* libxslt/pattern.c: started adding xsltTestCompMatch() * libxslt/pattern.c: started adding xsltTestCompMatch()

View File

@@ -8,6 +8,8 @@ libxslt_la_SOURCES = \
xslt.h \ xslt.h \
pattern.c \ pattern.c \
pattern.h \ pattern.h \
transform.c \
transform.h \
xsltInternals.h xsltInternals.h

View File

@@ -73,6 +73,7 @@ typedef xsltCompMatch *xsltCompMatchPtr;
struct _xsltCompMatch { struct _xsltCompMatch {
struct _xsltCompMatch *next; /* siblings in the name hash */ struct _xsltCompMatch *next; /* siblings in the name hash */
int priority; /* the priority */ int priority; /* the priority */
xsltTemplatePtr template; /* the associated template */
/* TODO fix the statically allocated size */ /* TODO fix the statically allocated size */
int nbStep; int nbStep;
@@ -125,8 +126,18 @@ xsltNewCompMatch(void) {
*/ */
void void
xsltFreeCompMatch(xsltCompMatchPtr comp) { xsltFreeCompMatch(xsltCompMatchPtr comp) {
xsltStepOpPtr op;
int i;
if (comp == NULL) if (comp == NULL)
return; return;
for (i = 0;i < comp->nbStep;i++) {
op = &comp->steps[i];
if (op->value != NULL)
xmlFree(op->value);
if (op->value2 != NULL)
xmlFree(op->value2);
}
memset(comp, -1, sizeof(xsltCompMatch)); memset(comp, -1, sizeof(xsltCompMatch));
xmlFree(comp); xmlFree(comp);
} }
@@ -680,6 +691,7 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur) {
pat = xsltCompilePattern(cur->match); pat = xsltCompilePattern(cur->match);
if (pat == NULL) if (pat == NULL)
return(-1); return(-1);
pat->template = cur;
if (cur->priority != XSLT_PAT_NO_PRIORITY) if (cur->priority != XSLT_PAT_NO_PRIORITY)
pat->priority = cur->priority; pat->priority = cur->priority;
@@ -746,14 +758,14 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur) {
*/ */
if (list->priority <= pat->priority) { if (list->priority <= pat->priority) {
pat->next = list; pat->next = list;
xmlHashAddEntry(style->templatesHash, name, pat); xmlHashUpdateEntry(style->templatesHash, name, pat, NULL);
#ifdef DEBUG_PARSING #ifdef DEBUG_PARSING
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsltAddTemplate: added head hash for %s\n", name); "xsltAddTemplate: added head hash for %s\n", name);
#endif #endif
} else { } else {
while (list->next != NULL) { while (list->next != NULL) {
if (list->next->priority < pat->priority) if (list->next->priority <= pat->priority)
break; break;
} }
pat->next = list->next; pat->next = list->next;
@@ -775,6 +787,83 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur) {
*/ */
xsltTemplatePtr xsltTemplatePtr
xsltGetTemplate(xsltStylesheetPtr style, xmlNodePtr node) { xsltGetTemplate(xsltStylesheetPtr style, xmlNodePtr node) {
const xmlChar *name;
xsltCompMatchPtr list;
if ((style == NULL) || (node == NULL))
return(NULL);
/* TODO : handle IDs/keys here ! */
if (style->templatesHash == NULL)
return(NULL);
/*
* Use a name as selector
*/
switch (node->type) {
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
case XML_PI_NODE:
name = node->name;
break;
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
name = (const xmlChar *)"/";
break;
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
case XML_COMMENT_NODE:
case XML_DOCUMENT_TYPE_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_NOTATION_NODE:
case XML_DTD_NODE:
case XML_ELEMENT_DECL:
case XML_ATTRIBUTE_DECL:
case XML_ENTITY_DECL:
case XML_NAMESPACE_DECL:
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
return(NULL);
default:
return(NULL);
}
if (name == NULL)
return(NULL);
/*
* find the list of appliable expressions based on the name
*/
list = (xsltCompMatchPtr) xmlHashLookup(style->templatesHash, name);
if (list == NULL) {
#ifdef DEBUG_MATCHING
xsltGenericError(xsltGenericErrorContext,
"xsltGetTemplate: empty set for %s\n", name);
#endif
return(NULL);
}
while (list != NULL) {
if (xsltTestCompMatch(list, node))
return(list->template);
list = list->next;
}
return(NULL); return(NULL);
} }
/**
* xsltFreeTemplateHashes:
* @style: an XSLT stylesheet
*
* Free up the memory used by xsltAddTemplate/xsltGetTemplate mechanism
*/
void
xsltFreeTemplateHashes(xsltStylesheetPtr style) {
if (style->templatesHash != NULL)
xmlHashFree((xmlHashTablePtr) style->templatesHash,
(xmlHashDeallocator) xsltFreeCompMatchList);
}

View File

@@ -19,7 +19,7 @@ int xsltAddTemplate (xsltStylesheetPtr style,
xsltTemplatePtr cur); xsltTemplatePtr cur);
xsltTemplatePtr xsltGetTemplate (xsltStylesheetPtr style, xsltTemplatePtr xsltGetTemplate (xsltStylesheetPtr style,
xmlNodePtr node); xmlNodePtr node);
void xsltFreeTemplateHashes (xsltStylesheetPtr style);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

187
libxslt/transform.c Normal file
View File

@@ -0,0 +1,187 @@
/*
* transform.c: Implemetation of the XSL Transformation 1.0 engine
* transform part, i.e. applying a Stylesheet to a document
*
* 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/parser.h>
#include <libxml/tree.h>
#include <libxml/valid.h>
#include <libxml/hash.h>
#include <libxml/xmlerror.h>
#include <libxml/xpath.h>
#include <libxml/HTMLtree.h>
#include "xslt.h"
#include "xsltInternals.h"
#include "pattern.h"
#include "transform.h"
#define DEBUG_PROCESS
/*
* To cleanup
*/
xmlChar *xmlSplitQName2(const xmlChar *name, xmlChar **prefix);
/*
* There is no XSLT specific error reporting module yet
*/
#define xsltGenericError xmlGenericError
#define xsltGenericErrorContext xmlGenericErrorContext
/*
* Useful macros
*/
#define TODO \
xsltGenericError(xsltGenericErrorContext, \
"Unimplemented block at %s:%d\n", \
__FILE__, __LINE__);
#define STRANGE \
xsltGenericError(xsltGenericErrorContext, \
"Internal error at %s:%d\n", \
__FILE__, __LINE__);
/*
* Types are private:
*/
typedef enum xsltOutputType {
XSLT_OUTPUT_XML = 0,
XSLT_OUTPUT_HTML,
XSLT_OUTPUT_TEXT
} xsltOutputType;
typedef struct _xsltTransformContext xsltTransformContext;
typedef xsltTransformContext *xsltTransformContextPtr;
struct _xsltTransformContext {
xsltOutputType type; /* the type of output */
xmlNodePtr node; /* the current node */
xmlNodeSetPtr nodeList; /* the current node list */
xmlNodePtr output; /* output node */
xmlXPathContextPtr xpathCtxt; /* the XPath context */
};
/************************************************************************
* *
*
* *
************************************************************************/
/**
* xsltNewTransformContext:
*
* Create a new XSLT TransformContext
*
* Returns the newly allocated xsltTransformContextPtr or NULL in case of error
*/
xsltTransformContextPtr
xsltNewTransformContext(void) {
xsltTransformContextPtr cur;
cur = (xsltTransformContextPtr) xmlMalloc(sizeof(xsltTransformContext));
if (cur == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltNewTransformContext : malloc failed\n");
return(NULL);
}
memset(cur, 0, sizeof(xsltTransformContext));
return(cur);
}
/**
* xsltFreeTransformContext:
* @ctxt: an XSLT parser context
*
* Free up the memory allocated by @ctxt
*/
void
xsltFreeTransformContext(xsltTransformContextPtr ctxt) {
if (ctxt == NULL)
return;
memset(ctxt, -1, sizeof(xsltTransformContext));
xmlFree(ctxt);
}
/************************************************************************
* *
*
* *
************************************************************************/
/**
* xsltApplyStylesheet:
* @style: a parsed XSLT stylesheet
* @doc: a parsed XML document
*
* Apply the stylesheet to the document
* NOTE: This may lead to a non-wellformed output XML wise !
*
* Returns the result document or NULL in case of error
*/
xmlDocPtr
xsltApplyStylesheet(xsltStylesheetPtr style, xmlDocPtr doc) {
xmlDocPtr res = NULL;
xsltTransformContextPtr ctxt = NULL;
if ((style == NULL) || (doc == NULL))
return(NULL);
ctxt = xsltNewTransformContext();
if (ctxt == NULL)
return(NULL);
if ((style->method != NULL) &&
(!xmlStrEqual(style->method, (const xmlChar *) "xml"))) {
if (xmlStrEqual(style->method, (const xmlChar *) "html")) {
ctxt->type = XSLT_OUTPUT_HTML;
res = htmlNewDoc(style->doctypePublic, style->doctypeSystem);
if (res == NULL)
goto error;
} else if (xmlStrEqual(style->method, (const xmlChar *) "text")) {
ctxt->type = XSLT_OUTPUT_TEXT;
TODO
goto error;
} else {
xsltGenericError(xsltGenericErrorContext,
"xsltApplyStylesheet: insupported method %s\n",
style->method);
goto error;
}
} else {
ctxt->type = XSLT_OUTPUT_XML;
res = xmlNewDoc(style->version);
if (res == NULL)
goto error;
}
if (style->encoding != NULL)
doc->encoding = xmlStrdup(style->encoding);
/*
res->intSubset = xmlCreateIntSubset(
*/
xsltFreeTransformContext(ctxt);
return(res);
error:
if (res != NULL)
xmlFreeDoc(res);
if (ctxt != NULL)
xsltFreeTransformContext(ctxt);
return(NULL);
}

30
libxslt/transform.h Normal file
View File

@@ -0,0 +1,30 @@
/*
* transform.h: Interfaces, constants and types related to the XSLT engine
* transform part.
*
* See Copyright for the status of this software.
*
* Daniel.Veillard@imag.fr
*/
#ifndef __XML_XSLT_TRANSFORM_H__
#define __XML_XSLT_TRANSFORM_H__
#include <libxml/tree.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Interfaces
*/
xmlDocPtr xsltApplyStylesheet (xsltStylesheetPtr style,
xmlDocPtr doc);
#ifdef __cplusplus
}
#endif
#endif /* __XML_XSLT_TRANSFORM_H__ */

View File

@@ -123,6 +123,11 @@ void
xsltFreeTemplate(xsltTemplatePtr template) { xsltFreeTemplate(xsltTemplatePtr template) {
if (template == NULL) if (template == NULL)
return; return;
if (template->match) xmlFree(template->match);
if (template->name) xmlFree(template->name);
if (template->nameURI) xmlFree(template->nameURI);
if (template->mode) xmlFree(template->mode);
if (template->modeURI) xmlFree(template->modeURI);
memset(template, -1, sizeof(xsltTemplate)); memset(template, -1, sizeof(xsltTemplate));
xmlFree(template); xmlFree(template);
} }
@@ -178,6 +183,8 @@ void
xsltFreeStylesheet(xsltStylesheetPtr sheet) { xsltFreeStylesheet(xsltStylesheetPtr sheet) {
if (sheet == NULL) if (sheet == NULL)
return; return;
xsltFreeTemplateHashes(sheet);
xsltFreeTemplateList(sheet->templates); xsltFreeTemplateList(sheet->templates);
if (sheet->doc != NULL) if (sheet->doc != NULL)
xmlFreeDoc(sheet->doc); xmlFreeDoc(sheet->doc);

View File

@@ -7,9 +7,12 @@
*/ */
#include <string.h> #include <string.h>
#include <libxml/xmlversion.h>
#include <libxml/xmlmemory.h> #include <libxml/xmlmemory.h>
#include <libxml/debugXML.h>
#include <libxslt/xslt.h> #include <libxslt/xslt.h>
#include <libxslt/xsltInternals.h> #include <libxslt/xsltInternals.h>
#include <libxslt/transform.h>
static int debug = 0; static int debug = 0;
@@ -17,6 +20,7 @@ int
main(int argc, char **argv) { main(int argc, char **argv) {
int i; int i;
xsltStylesheetPtr cur; xsltStylesheetPtr cur;
xmlDocPtr doc, res;
LIBXML_TEST_VERSION LIBXML_TEST_VERSION
for (i = 1; i < argc ; i++) { for (i = 1; i < argc ; i++) {
@@ -26,11 +30,34 @@ main(int argc, char **argv) {
xmlSubstituteEntitiesDefault(1); xmlSubstituteEntitiesDefault(1);
for (i = 1; i < argc ; i++) { for (i = 1; i < argc ; i++) {
if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) { if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
cur = xsltParseStylesheetFile(argv[i]); cur = xsltParseStylesheetFile((const xmlChar *)argv[i]);
xsltFreeStylesheet(cur); i++;
break; break;
} }
} }
for (;i < argc ; i++) {
doc = xmlParseFile(argv[i]);
if (doc == NULL) {
fprintf(stderr, "unable to parse %s\n", argv[i]);
continue;
}
res = xsltApplyStylesheet(cur, doc);
xmlFreeDoc(doc);
if (res == NULL) {
fprintf(stderr, "no result for %s\n", argv[i]);
continue;
}
#ifdef LIBXML_DEBUG_ENABLED
if (debug)
xmlDebugDumpDocument(stdout, res);
else
#endif
xmlDocDump(stdout, res);
xmlFreeDoc(res);
}
if (cur != NULL)
xsltFreeStylesheet(cur);
xmlCleanupParser(); xmlCleanupParser();
xmlMemoryDump(); xmlMemoryDump();
return(0); return(0);