1 /* This file implements a XSLT engine working on Gdome documents. In fact,
2 * it just maps Gdome documents to libxml documents back and forth, and
3 * applyes the transformation on libxml documents using libxlt.
5 * The code is largely based on the code of T.J. Mather's XML::GDOME::XSLT
6 * Perl module (http://kobesearch.cpan.org/search?dist=XML-GDOME-XSLT)
9 * Claudio Sacerdoti Coen <sacerdot@cs.unibo.it>
10 * Stefano Zacchiroli <zack@cs.unibo.it>
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 * For more information, please send an email to {sacerdot,zack}@cs.unibo.it
33 #include <libxslt/xsltconfig.h>
34 #include <libxslt/xslt.h>
35 #include <libxslt/xsltutils.h>
36 #include <libxslt/transform.h>
37 #include <libxslt/imports.h>
38 #include "gdome_xslt.h"
40 // Begin of Gdome internals exposed
41 typedef struct _Gdome_xml_Document Gdome_xml_Document;
42 struct _Gdome_xml_Document {
44 const GdomeDocumentVtab* vtab;
47 GdomeAccessType accessType;
50 GdomeNode* gdome_xml_n_mkref(xmlNode* n);
51 // End of Gdome internals exposed
53 // Begin of the abstraction of Gdome internals. Uses the Gdome internals exposed
54 xmlDocPtr libxml_of_gdome(GdomeDocument* doc)
56 return ((Gdome_xml_Document*)doc)->n;
59 GdomeDocument* gdome_of_libxml(xmlDocPtr n)
61 return (GdomeDocument*)gdome_xml_n_mkref((xmlNode*)n);
63 // End of the abstraction of Gdome internals. Uses the Gdome internals exposed.
67 // From now on no Gdome internal should be used directly.
69 /******************************/
70 /* XSLT stylesheet Processing */
71 /******************************/
73 xsltStylesheetPtr processStylesheet(GdomeDocument* style)
76 xmlDocPtr style_libxml;
81 style_libxml = libxml_of_gdome(style);
82 style_copy = xmlCopyDoc(style_libxml, 1);
83 style_copy->URL = xmlStrdup(style_libxml->URL);
85 xsltSetGenericDebugFunc(NULL, NULL);
87 return xsltParseStylesheetDoc(style_copy);
90 /*******************************/
91 /* XSLT stylesheet Application */
92 /*******************************/
94 GdomeDocument* applyStylesheet(GdomeDocument* source, xsltStylesheetPtr
95 style_libxslt, const char** params)
97 xmlDocPtr source_libxml;
98 xmlDocPtr output_libxml;
100 if (source == NULL) return NULL;
101 source_libxml = libxml_of_gdome(source);
103 xsltSetGenericDebugFunc(NULL, NULL);
105 output_libxml = xsltApplyStylesheet(style_libxslt, source_libxml,
108 if (output_libxml == NULL) return NULL;
110 return gdome_of_libxml(output_libxml);
117 int saveResultToFilename (const char* name, GdomeDocument* result,
118 xsltStylesheetPtr style_libxslt, int compression)
120 xmlDocPtr result_libxml;
122 if (result == NULL) return -1;
123 result_libxml = libxml_of_gdome(result);
125 xsltSetGenericDebugFunc(NULL, NULL);
127 return xsltSaveResultToFilename(name, result_libxml,
128 style_libxslt, compression);
131 int saveResultToFile (FILE* file, GdomeDocument* result,
132 xsltStylesheetPtr style_libxslt)
134 xmlDocPtr result_libxml;
136 if (result == NULL) return -1;
137 result_libxml = libxml_of_gdome(result);
139 xsltSetGenericDebugFunc(NULL, NULL);
141 return xsltSaveResultToFile(file, result_libxml, style_libxslt);
144 int saveResultToFd (int fd, GdomeDocument* result, xsltStylesheetPtr
147 xmlDocPtr result_libxml;
149 if (result == NULL) return -1;
150 result_libxml = libxml_of_gdome(result);
152 xsltSetGenericDebugFunc(NULL, NULL);
154 return xsltSaveResultToFd(fd, result_libxml, style_libxslt);
157 /**********************************************/
158 /* Error and Debugging Callbacks Registration */
159 /**********************************************/
161 /* max size of a single message passed to callbacks */
162 #define MAX_MSG_SIZE 1024
163 #define TRUNCATED_MSG "... TRUNCATED ..."
164 #define TRUNCATED_MSG_LEN strlen(TRUNCATED_MSG)
166 /* ERROR callbacks */
168 /* user provided error callback, needs a string input */
169 static gdomeXsltMsgCallback errorUserCallback = NULL;
171 /* libxslt like error callback, ignore context, builds a string
172 * input for user provided error callback and invoke it */
173 void gdomeXsltErrorCallback (void *ctx, const char *msg, ...) {
175 char buf[MAX_MSG_SIZE];
177 if (errorUserCallback == NULL)
181 if (vsnprintf(buf, MAX_MSG_SIZE, msg, args) > MAX_MSG_SIZE - 1)
182 { /* message truncated; write TRUNCATED_MSG on it */
183 strncpy(buf+(strlen(buf) - TRUNCATED_MSG_LEN),
184 TRUNCATED_MSG, TRUNCATED_MSG_LEN);
188 (*errorUserCallback) (buf);
193 /* set user provided error callback */
194 void setErrorCallback (gdomeXsltMsgCallback callback)
196 errorUserCallback = callback;
197 xsltSetGenericErrorFunc(NULL,
198 (callback == NULL ? NULL : gdomeXsltErrorCallback));
203 /* DEBUG callbacks */
205 /* user provided debug callback, needs a string input */
206 static gdomeXsltMsgCallback debugUserCallback = NULL;
208 /* libxslt like debug callback, ignore context, builds a string
209 * input for user provided debug callback and invoke it */
210 void gdomeXsltDebugCallback (void *ctx, const char *msg, ...) {
212 char buf[MAX_MSG_SIZE];
214 if (debugUserCallback == NULL)
218 if (vsnprintf(buf, MAX_MSG_SIZE, msg, args) > MAX_MSG_SIZE - 1)
219 { /* message truncated; write TRUNCATED_MSG on it */
220 strncpy(buf+(strlen(buf) - TRUNCATED_MSG_LEN),
221 TRUNCATED_MSG, TRUNCATED_MSG_LEN);
225 (*debugUserCallback) (buf);
230 /* set user provided debug callback */
231 void setDebugCallback (gdomeXsltMsgCallback callback)
233 debugUserCallback = callback;
234 xsltSetGenericDebugFunc(NULL,
235 (callback == NULL ? NULL : gdomeXsltDebugCallback));