mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +08:00
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.
This commit is contained in:
parent
f21d5b61ce
commit
c0e977c18f
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.204 2007/01/07 22:49:55 petere Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.205 2007/01/10 20:33:54 petere Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -2654,7 +2654,6 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
|
||||
char *str;
|
||||
ListCell *arg;
|
||||
ListCell *narg;
|
||||
bool found_arg;
|
||||
int i;
|
||||
|
||||
if (isDone)
|
||||
@ -2682,55 +2681,6 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
|
||||
}
|
||||
break;
|
||||
|
||||
case IS_XMLELEMENT:
|
||||
initStringInfo(&buf);
|
||||
*isNull = false;
|
||||
appendStringInfo(&buf, "<%s", 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);
|
||||
appendStringInfo(&buf, " %s=\"%s\"", argname, str);
|
||||
pfree(str);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
found_arg = false;
|
||||
foreach(arg, xmlExpr->args)
|
||||
{
|
||||
ExprState *e = (ExprState *) lfirst(arg);
|
||||
|
||||
value = ExecEvalExpr(e, econtext, &isnull, NULL);
|
||||
if (!isnull)
|
||||
{
|
||||
if (!found_arg)
|
||||
{
|
||||
appendStringInfoChar(&buf, '>');
|
||||
found_arg = true;
|
||||
}
|
||||
|
||||
/* we know the value is XML type */
|
||||
str = DatumGetCString(DirectFunctionCall1(xml_out,
|
||||
value));
|
||||
appendStringInfoString(&buf, str);
|
||||
pfree(str);
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_arg)
|
||||
appendStringInfo(&buf, "/>");
|
||||
else
|
||||
appendStringInfo(&buf, "</%s>", xexpr->name);
|
||||
break;
|
||||
|
||||
case IS_XMLFOREST:
|
||||
initStringInfo(&buf);
|
||||
i = 0;
|
||||
@ -2754,6 +2704,11 @@ ExecEvalXml(XmlExprState *xmlExpr, ExprContext *econtext,
|
||||
break;
|
||||
|
||||
/* The remaining cases don't need to set up buf */
|
||||
case IS_XMLELEMENT:
|
||||
*isNull = false;
|
||||
return PointerGetDatum(xmlelement(xmlExpr, econtext));
|
||||
break;
|
||||
|
||||
case IS_XMLPARSE:
|
||||
{
|
||||
ExprState *e;
|
||||
|
@ -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"
|
||||
@ -239,6 +241,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)
|
||||
{
|
||||
@ -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;
|
||||
|
@ -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/include/utils/xml.h,v 1.7 2007/01/07 22:49:56 petere Exp $
|
||||
* $PostgreSQL: pgsql/src/include/utils/xml.h,v 1.8 2007/01/10 20:33:54 petere Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -16,6 +16,7 @@
|
||||
#define XML_H
|
||||
|
||||
#include "fmgr.h"
|
||||
#include "nodes/execnodes.h"
|
||||
|
||||
typedef struct varlena xmltype;
|
||||
|
||||
@ -32,6 +33,7 @@ extern Datum xmlcomment(PG_FUNCTION_ARGS);
|
||||
extern Datum texttoxml(PG_FUNCTION_ARGS);
|
||||
extern Datum xmlvalidate(PG_FUNCTION_ARGS);
|
||||
|
||||
extern xmltype *xmlelement(XmlExprState *xmlExpr, ExprContext *econtext);
|
||||
extern xmltype *xmlparse(text *data, bool is_doc, bool preserve_whitespace);
|
||||
extern xmltype *xmlpi(char *target, text *arg, bool arg_is_null, bool *result_is_null);
|
||||
extern xmltype *xmlroot(xmltype *data, text *version, int standalone);
|
||||
|
Loading…
Reference in New Issue
Block a user