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
);
43 PG_FUNCTION_INFO_V1(xslt_process
);
46 xslt_process(PG_FUNCTION_ARGS
)
48 text
*doct
= PG_GETARG_TEXT_P(0);
49 text
*ssheet
= PG_GETARG_TEXT_P(1);
51 const char *params
[MAXPARAMS
+ 1]; /* +1 for the terminator */
52 xsltStylesheetPtr stylesheet
= NULL
;
55 xmlDocPtr ssdoc
= NULL
;
60 if (fcinfo
->nargs
== 3)
62 paramstr
= PG_GETARG_TEXT_P(2);
63 parse_params(params
, paramstr
);
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
);
77 doctree
= xmlParseFile(text_to_cstring(doct
));
82 elog_error(ERROR
, "error parsing XML document", 0);
87 /* Same for stylesheet */
88 if (VARDATA(ssheet
)[0] == '<')
90 ssdoc
= xmlParseMemory((char *) VARDATA(ssheet
),
91 VARSIZE(ssheet
) - VARHDRSZ
);
96 elog_error(ERROR
, "error parsing stylesheet as XML document", 0);
100 stylesheet
= xsltParseStylesheetDoc(ssdoc
);
103 stylesheet
= xsltParseStylesheetFile((xmlChar
*) text_to_cstring(ssheet
));
106 if (stylesheet
== NULL
)
109 xsltCleanupGlobals();
111 elog_error(ERROR
, "failed to parse stylesheet", 0);
115 restree
= xsltApplyStylesheet(stylesheet
, doctree
, params
);
116 resstat
= xsltSaveResultToString(&resstr
, &reslen
, restree
, stylesheet
);
118 xsltFreeStylesheet(stylesheet
);
122 xsltCleanupGlobals();
128 PG_RETURN_TEXT_P(cstring_to_text_with_len((char *) resstr
, reslen
));
133 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
);
163 pos
= strstr(pos
, itsep
);
174 params
[i
+ 1] = NULL
;