4 * XSLT processing functions (requiring libxslt)
6 * John Gray, for Torchbox 2003-04-01
10 #include "executor/spi.h"
13 #include "miscadmin.h"
14 #include "utils/builtins.h"
18 #include <libxml/xpath.h>
19 #include <libxml/tree.h>
20 #include <libxml/xmlmemory.h>
22 /* libxslt includes */
24 #include <libxslt/xslt.h>
25 #include <libxslt/xsltInternals.h>
26 #include <libxslt/transform.h>
27 #include <libxslt/xsltutils.h>
30 /* declarations to come from xpath.c */
31 extern void elog_error(int level
, char *explain
, int force
);
32 extern void pgxml_parser_init();
33 extern xmlChar
*pgxml_texttoxmlchar(text
*textstring
);
36 static void parse_params(const char **params
, text
*paramstr
);
38 Datum
xslt_process(PG_FUNCTION_ARGS
);
41 #define MAXPARAMS 20 /* must be even, see parse_params() */
44 PG_FUNCTION_INFO_V1(xslt_process
);
47 xslt_process(PG_FUNCTION_ARGS
)
49 text
*doct
= PG_GETARG_TEXT_P(0);
50 text
*ssheet
= PG_GETARG_TEXT_P(1);
52 const char *params
[MAXPARAMS
+ 1]; /* +1 for the terminator */
53 xsltStylesheetPtr stylesheet
= NULL
;
56 xmlDocPtr ssdoc
= NULL
;
61 if (fcinfo
->nargs
== 3)
63 paramstr
= PG_GETARG_TEXT_P(2);
64 parse_params(params
, paramstr
);
73 /* Check to see if document is a file or a literal */
75 if (VARDATA(doct
)[0] == '<')
76 doctree
= xmlParseMemory((char *) VARDATA(doct
), VARSIZE(doct
) - VARHDRSZ
);
78 doctree
= xmlParseFile(text_to_cstring(doct
));
83 elog_error(ERROR
, "error parsing XML document", 0);
88 /* Same for stylesheet */
89 if (VARDATA(ssheet
)[0] == '<')
91 ssdoc
= xmlParseMemory((char *) VARDATA(ssheet
),
92 VARSIZE(ssheet
) - VARHDRSZ
);
97 elog_error(ERROR
, "error parsing stylesheet as XML document", 0);
101 stylesheet
= xsltParseStylesheetDoc(ssdoc
);
104 stylesheet
= xsltParseStylesheetFile((xmlChar
*) text_to_cstring(ssheet
));
107 if (stylesheet
== NULL
)
110 xsltCleanupGlobals();
112 elog_error(ERROR
, "failed to parse stylesheet", 0);
116 restree
= xsltApplyStylesheet(stylesheet
, doctree
, params
);
117 resstat
= xsltSaveResultToString(&resstr
, &reslen
, restree
, stylesheet
);
119 xsltFreeStylesheet(stylesheet
);
123 xsltCleanupGlobals();
129 PG_RETURN_TEXT_P(cstring_to_text_with_len((char *) resstr
, reslen
));
134 parse_params(const char **params
, text
*paramstr
)
142 pstr
= text_to_cstring(paramstr
);
146 for (i
= 0; i
< MAXPARAMS
; i
++)
149 pos
= strstr(pos
, nvsep
);
157 /* No equal sign, so ignore this "parameter" */
158 /* We'll reset params[i] to NULL below the loop */
163 /* since MAXPARAMS is even, we still have i < MAXPARAMS */
165 pos
= strstr(pos
, itsep
);