20 #include <libxml/xpath.h>
21 #include <libxml/tree.h>
22 #include <libxml/xmlmemory.h>
23 #include <libxml/xmlerror.h>
24 #include <libxml/parserInternals.h>
38 xmlXPathObjectPtr
res;
44 xmlChar *toptagname, xmlChar *septagname,
48 xmlChar *septag, xmlChar *plainsep);
77 xmlSubstituteEntitiesDefault(1);
78 xmlLoadExtDtdDefaultValue = 1;
98 tt = xmlEncodeSpecialChars(NULL, ts);
130 buf = xmlBufferCreate();
132 if ((toptagname != NULL) && (xmlStrlen(toptagname) > 0))
134 xmlBufferWriteChar(
buf,
"<");
135 xmlBufferWriteCHAR(
buf, toptagname);
136 xmlBufferWriteChar(
buf,
">");
140 for (
i = 0;
i < nodeset->nodeNr;
i++)
142 if (plainsep != NULL)
144 xmlBufferWriteCHAR(
buf,
145 xmlXPathCastNodeToString(nodeset->nodeTab[
i]));
148 if (
i < (nodeset->nodeNr) - 1)
149 xmlBufferWriteChar(
buf, (
char *) plainsep);
153 if ((septagname != NULL) && (xmlStrlen(septagname) > 0))
155 xmlBufferWriteChar(
buf,
"<");
156 xmlBufferWriteCHAR(
buf, septagname);
157 xmlBufferWriteChar(
buf,
">");
160 nodeset->nodeTab[
i]->doc,
164 if ((septagname != NULL) && (xmlStrlen(septagname) > 0))
166 xmlBufferWriteChar(
buf,
"</");
167 xmlBufferWriteCHAR(
buf, septagname);
168 xmlBufferWriteChar(
buf,
">");
174 if ((toptagname != NULL) && (xmlStrlen(toptagname) > 0))
176 xmlBufferWriteChar(
buf,
"</");
177 xmlBufferWriteCHAR(
buf, toptagname);
178 xmlBufferWriteChar(
buf,
">");
180 result = xmlStrdup(
buf->content);
212 xmlXPathObjectPtr
res;
244 xmlXPathObjectPtr
res;
273 xmlXPathObjectPtr
res;
285 memcpy((
char *)
xpath,
"string(", 7);
287 xpath[pathsize + 7] =
')';
288 xpath[pathsize + 8] =
'\0';
313 xmlXPathObjectPtr
res;
325 fRes = xmlXPathCastToNumber(
res);
329 if (xmlXPathIsNaN(fRes))
345 xmlXPathObjectPtr
res;
357 bRes = xmlXPathCastToBoolean(
res);
368 static xmlXPathObjectPtr
373 xmlXPathCompExprPtr comppath;
376 workspace->
ctxt = NULL;
377 workspace->
res = NULL;
385 if (workspace->
doctree != NULL)
387 workspace->
ctxt = xmlXPathNewContext(workspace->
doctree);
388 workspace->
ctxt->node = xmlDocGetRootElement(workspace->
doctree);
391 comppath = xmlXPathCompile(
xpath);
392 if (comppath == NULL)
394 "XPath Syntax Error");
397 workspace->
res = xmlXPathCompiledEval(comppath, workspace->
ctxt);
399 xmlXPathFreeCompExpr(comppath);
412 if (workspace->
res == NULL)
417 return workspace->
res;
425 xmlXPathFreeObject(workspace->
res);
426 workspace->
res = NULL;
428 xmlXPathFreeContext(workspace->
ctxt);
429 workspace->
ctxt = NULL;
431 xmlFreeDoc(workspace->
doctree);
456 xpresstr = xmlStrdup(
res->stringval);
461 xpresstr = xmlStrdup((
const xmlChar *)
"<unsupported/>");
501 const char *pathsep =
"|";
512 volatile xmlDocPtr doctree = NULL;
519 (
errcode(ERRCODE_SYNTAX_ERROR),
520 errmsg(
"xpath_table must have at least one output column")));
544 xpaths[numpaths++] = (xmlChar *) pos;
545 pos = strstr(pos, pathsep);
566 elog(
ERROR,
"xpath_table: SPI_connect returned %d", ret);
569 elog(
ERROR,
"xpath_table: SPI execution failed for query %s",
574 spi_tupdesc = tuptable->
tupdesc;
581 if (spi_tupdesc->
natts != 2)
584 errmsg(
"expression returning multiple columns is not valid in parameter list"),
585 errdetail(
"Expected two columns in SPI result, got %d.", spi_tupdesc->
natts)));
599 for (
i = 0;
i < proc;
i++)
603 xmlXPathContextPtr ctxt;
604 xmlXPathObjectPtr
res;
606 xmlXPathCompExprPtr comppath;
610 spi_tuple = tuptable->
vals[
i];
627 doctree = xmlParseMemory(xmldoc, strlen(xmldoc));
647 for (
j = 0;
j < numpaths;
j++)
649 ctxt = xmlXPathNewContext(doctree);
650 ctxt->node = xmlDocGetRootElement(doctree);
653 comppath = xmlXPathCompile(xpaths[
j]);
654 if (comppath == NULL)
656 ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
657 "XPath Syntax Error");
660 res = xmlXPathCompiledEval(comppath, ctxt);
661 xmlXPathFreeCompExpr(comppath);
669 if (
res->nodesetval != NULL &&
670 rownr < res->nodesetval->nodeNr)
672 resstr = xmlXPathCastNodeToString(
res->nodesetval->nodeTab[rownr]);
681 resstr = xmlStrdup(
res->stringval);
686 resstr = xmlStrdup((
const xmlChar *)
"<unsupported/>");
693 values[
j + 1] = (
char *) resstr;
695 xmlXPathFreeContext(ctxt);
707 }
while (had_values);
static Datum values[MAXATTR]
static void PGresult * res
elog(ERROR, "%s: %s", p2, msg)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
#define PG_GETARG_TEXT_PP(n)
#define PG_RETURN_TEXT_P(x)
#define PG_RETURN_FLOAT4(x)
#define PG_RETURN_BOOL(x)
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
#define MAT_SRF_USE_EXPECTED_DESC
void heap_freetuple(HeapTuple htup)
void pfree(void *pointer)
SPITupleTable * SPI_tuptable
int SPI_exec(const char *src, long tcount)
char * SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
void appendStringInfo(StringInfo str, const char *fmt,...)
void initStringInfo(StringInfo str)
Tuplestorestate * setResult
void tuplestore_puttuple(Tuplestorestate *state, HeapTuple tuple)
#define VARSIZE_ANY_EXHDR(PTR)
char * text_to_cstring(const text *t)
text * cstring_to_text(const char *s)
Datum xpath(PG_FUNCTION_ARGS)
struct PgXmlErrorContext PgXmlErrorContext
void xml_ereport(PgXmlErrorContext *errcxt, int level, int sqlcode, const char *msg)
void pg_xml_done(PgXmlErrorContext *errcxt, bool isError)
PgXmlErrorContext * pg_xml_init(PgXmlStrictness strictness)
@ PG_XML_STRICTNESS_LEGACY
static text * pgxml_result_to_text(xmlXPathObjectPtr res, xmlChar *toptag, xmlChar *septag, xmlChar *plainsep)
Datum xpath_bool(PG_FUNCTION_ARGS)
Datum xpath_number(PG_FUNCTION_ARGS)
Datum xpath_table(PG_FUNCTION_ARGS)
static xmlXPathObjectPtr pgxml_xpath(text *document, xmlChar *xpath, xpath_workspace *workspace)
static xmlChar * pgxml_texttoxmlchar(text *textstring)
PgXmlErrorContext * pgxml_parser_init(PgXmlStrictness strictness)
Datum xpath_string(PG_FUNCTION_ARGS)
static void cleanup_workspace(xpath_workspace *workspace)
Datum xml_encode_special_chars(PG_FUNCTION_ARGS)
Datum xpath_list(PG_FUNCTION_ARGS)
static xmlChar * pgxmlNodeSetToText(xmlNodeSetPtr nodeset, xmlChar *toptagname, xmlChar *septagname, xmlChar *plainsep)
Datum xpath_nodeset(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(xml_encode_special_chars)