Start background writer during archive recovery. Background writer now performs
[PostgreSQL.git] / contrib / xml2 / xslt_proc.c
blob4f96164ff5781fcf46f0505ff7448715ca9c3798
1 /*
2 * $PostgreSQL$
4 * XSLT processing functions (requiring libxslt)
6 * John Gray, for Torchbox 2003-04-01
7 */
8 #include "postgres.h"
10 #include "executor/spi.h"
11 #include "fmgr.h"
12 #include "funcapi.h"
13 #include "miscadmin.h"
14 #include "utils/builtins.h"
16 /* libxml includes */
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);
35 /* local defs */
36 static void parse_params(const char **params, text *paramstr);
38 Datum xslt_process(PG_FUNCTION_ARGS);
41 #define MAXPARAMS 20
43 PG_FUNCTION_INFO_V1(xslt_process);
45 Datum
46 xslt_process(PG_FUNCTION_ARGS)
48 text *doct = PG_GETARG_TEXT_P(0);
49 text *ssheet = PG_GETARG_TEXT_P(1);
50 text *paramstr;
51 const char *params[MAXPARAMS + 1]; /* +1 for the terminator */
52 xsltStylesheetPtr stylesheet = NULL;
53 xmlDocPtr doctree;
54 xmlDocPtr restree;
55 xmlDocPtr ssdoc = NULL;
56 xmlChar *resstr;
57 int resstat;
58 int reslen;
60 if (fcinfo->nargs == 3)
62 paramstr = PG_GETARG_TEXT_P(2);
63 parse_params(params, paramstr);
65 else
66 /* No parameters */
67 params[0] = NULL;
69 /* Setup parser */
70 pgxml_parser_init();
72 /* Check to see if document is a file or a literal */
74 if (VARDATA(doct)[0] == '<')
75 doctree = xmlParseMemory((char *) VARDATA(doct), VARSIZE(doct) - VARHDRSZ);
76 else
77 doctree = xmlParseFile(text_to_cstring(doct));
79 if (doctree == NULL)
81 xmlCleanupParser();
82 elog_error(ERROR, "error parsing XML document", 0);
84 PG_RETURN_NULL();
87 /* Same for stylesheet */
88 if (VARDATA(ssheet)[0] == '<')
90 ssdoc = xmlParseMemory((char *) VARDATA(ssheet),
91 VARSIZE(ssheet) - VARHDRSZ);
92 if (ssdoc == NULL)
94 xmlFreeDoc(doctree);
95 xmlCleanupParser();
96 elog_error(ERROR, "error parsing stylesheet as XML document", 0);
97 PG_RETURN_NULL();
100 stylesheet = xsltParseStylesheetDoc(ssdoc);
102 else
103 stylesheet = xsltParseStylesheetFile((xmlChar *) text_to_cstring(ssheet));
106 if (stylesheet == NULL)
108 xmlFreeDoc(doctree);
109 xsltCleanupGlobals();
110 xmlCleanupParser();
111 elog_error(ERROR, "failed to parse stylesheet", 0);
112 PG_RETURN_NULL();
115 restree = xsltApplyStylesheet(stylesheet, doctree, params);
116 resstat = xsltSaveResultToString(&resstr, &reslen, restree, stylesheet);
118 xsltFreeStylesheet(stylesheet);
119 xmlFreeDoc(restree);
120 xmlFreeDoc(doctree);
122 xsltCleanupGlobals();
123 xmlCleanupParser();
125 if (resstat < 0)
126 PG_RETURN_NULL();
128 PG_RETURN_TEXT_P(cstring_to_text_with_len((char *) resstr, reslen));
132 void
133 parse_params(const char **params, text *paramstr)
135 char *pos;
136 char *pstr;
138 int i;
139 char *nvsep = "=";
140 char *itsep = ",";
142 pstr = text_to_cstring(paramstr);
144 pos = pstr;
146 for (i = 0; i < MAXPARAMS; i++)
148 params[i] = pos;
149 pos = strstr(pos, nvsep);
150 if (pos != NULL)
152 *pos = '\0';
153 pos++;
155 else
157 params[i] = NULL;
158 break;
160 /* Value */
161 i++;
162 params[i] = pos;
163 pos = strstr(pos, itsep);
164 if (pos != NULL)
166 *pos = '\0';
167 pos++;
169 else
170 break;
173 if (i < MAXPARAMS)
174 params[i + 1] = NULL;