aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/xml.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2007-01-10 20:33:54 +0000
committerPeter Eisentraut <peter_e@gmx.net>2007-01-10 20:33:54 +0000
commitc0e977c18f1939cb0d948c51740aa8816d69c720 (patch)
tree71d15c5d3d7e793ff4beacfce21eb27b3d4c9d66 /src/backend/utils/adt/xml.c
parentf21d5b61ce4ecd60d4d671990f9c6b886e234809 (diff)
downloadpostgresql-c0e977c18f1939cb0d948c51740aa8816d69c720.tar.gz
postgresql-c0e977c18f1939cb0d948c51740aa8816d69c720.zip
Use libxml's xmlwriter API for producing XML elements, instead of doing
our own printing dance. This does a better job of quoting and escaping the values.
Diffstat (limited to 'src/backend/utils/adt/xml.c')
-rw-r--r--src/backend/utils/adt/xml.c74
1 files changed, 72 insertions, 2 deletions
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index 5137834efb1..5616259b29e 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.13 2007/01/07 22:49:56 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.14 2007/01/10 20:33:54 petere Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,8 +32,10 @@
#include <libxml/uri.h>
#include <libxml/xmlerror.h>
#include <libxml/xmlsave.h>
+#include <libxml/xmlwriter.h>
#endif /* USE_LIBXML */
+#include "executor/executor.h"
#include "fmgr.h"
#include "libpq/pqformat.h"
#include "mb/pg_wchar.h"
@@ -240,6 +242,71 @@ texttoxml(PG_FUNCTION_ARGS)
xmltype *
+xmlelement(XmlExprState *xmlExpr, ExprContext *econtext)
+{
+#ifdef USE_LIBXML
+ XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
+ int i;
+ ListCell *arg;
+ ListCell *narg;
+ bool isnull;
+ xmltype *result;
+ Datum value;
+ char *str;
+
+ xmlBufferPtr buf;
+ xmlTextWriterPtr writer;
+
+ buf = xmlBufferCreate();
+ writer = xmlNewTextWriterMemory(buf, 0);
+
+ xmlTextWriterStartElement(writer, (xmlChar *) xexpr->name);
+
+ i = 0;
+ forboth(arg, xmlExpr->named_args, narg, xexpr->arg_names)
+ {
+ ExprState *e = (ExprState *) lfirst(arg);
+ char *argname = strVal(lfirst(narg));
+
+ value = ExecEvalExpr(e, econtext, &isnull, NULL);
+ if (!isnull)
+ {
+ str = OutputFunctionCall(&xmlExpr->named_outfuncs[i], value);
+ xmlTextWriterWriteAttribute(writer, (xmlChar *) argname, (xmlChar *) str);
+ pfree(str);
+ }
+ i++;
+ }
+
+ foreach(arg, xmlExpr->args)
+ {
+ ExprState *e = (ExprState *) lfirst(arg);
+
+ value = ExecEvalExpr(e, econtext, &isnull, NULL);
+ if (!isnull)
+ {
+ /* we know the value is XML type */
+ str = DatumGetCString(DirectFunctionCall1(xml_out,
+ value));
+ xmlTextWriterWriteRaw(writer, (xmlChar *) str);
+ pfree(str);
+ }
+ }
+
+ xmlTextWriterEndElement(writer);
+ xmlFreeTextWriter(writer);
+
+ result = xmlBuffer_to_xmltype(buf);
+ xmlBufferFree(buf);
+ return result;
+#else
+ NO_XML_SUPPORT();
+ return NULL;
+#endif
+}
+
+
+xmltype *
xmlparse(text *data, bool is_document, bool preserve_whitespace)
{
#ifdef USE_LIBXML
@@ -313,6 +380,7 @@ xmltype *
xmlroot(xmltype *data, text *version, int standalone)
{
#ifdef USE_LIBXML
+ xmltype *result;
xmlDocPtr doc;
xmlBufferPtr buffer;
xmlSaveCtxtPtr save;
@@ -344,7 +412,9 @@ xmlroot(xmltype *data, text *version, int standalone)
xmlFreeDoc(doc);
- return xmlBuffer_to_xmltype(buffer);
+ result = xmlBuffer_to_xmltype(buffer);
+ xmlBufferFree(buffer);
+ return result;
#else
NO_XML_SUPPORT();
return NULL;