* 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.10 2007/01/05 22:19:42 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.11 2007/01/06 19:18:36 petere Exp $
*
*-------------------------------------------------------------------------
*/
#include <libxml/tree.h>
#include <libxml/uri.h>
#include <libxml/xmlerror.h>
+#include <libxml/xmlsave.h>
#endif /* USE_LIBXML */
#include "fmgr.h"
static StringInfo xml_err_buf = NULL;
static void xml_init(void);
+#ifdef NOT_USED
static void *xml_palloc(size_t size);
static void *xml_repalloc(void *ptr, size_t size);
static void xml_pfree(void *ptr);
static char *xml_pstrdup(const char *string);
+#endif
static void xml_ereport(int level, int sqlcode,
const char *msg, void *ctxt);
static void xml_errorHandler(void *ctxt, const char *msg, ...);
char *s = PG_GETARG_CSTRING(0);
size_t len;
xmltype *vardata;
+ xmlDocPtr doc;
len = strlen(s);
vardata = palloc(len + VARHDRSZ);
* Parse the data to check if it is well-formed XML data. Assume
* that ERROR occurred if parsing failed.
*/
- xml_parse(vardata, false, true);
+ doc = xml_parse(vardata, false, true);
+ xmlFreeDoc(doc);
PG_RETURN_XML_P(vardata);
#else
xmltype *result;
char *str;
int nbytes;
+ xmlDocPtr doc;
str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
* Parse the data to check if it is well-formed XML data. Assume
* that ERROR occurred if parsing failed.
*/
- xml_parse(result, false, true);
+ doc = xml_parse(result, false, true);
+ xmlFreeDoc(doc);
PG_RETURN_XML_P(result);
#else
return result;
}
+
+
+static xmltype *
+xmlBuffer_to_xmltype(xmlBufferPtr buf)
+{
+ int32 len;
+ xmltype *result;
+
+ len = xmlBufferLength(buf) + VARHDRSZ;
+ result = palloc(len);
+ VARATT_SIZEP(result) = len;
+ memcpy(VARDATA(result), xmlBufferContent(buf), len - VARHDRSZ);
+
+ return result;
+}
#endif
xmlparse(text *data, bool is_document, bool preserve_whitespace)
{
#ifdef USE_LIBXML
- xml_parse(data, is_document, preserve_whitespace);
+ xmlDocPtr doc;
+
+ doc = xml_parse(data, is_document, preserve_whitespace);
+ xmlFreeDoc(doc);
return (xmltype *) data;
#else
xmlroot(xmltype *data, text *version, int standalone)
{
#ifdef USE_LIBXML
- xmltype *result;
- StringInfoData buf;
+ xmlDocPtr doc;
+ xmlBufferPtr buffer;
+ xmlSaveCtxtPtr save;
- initStringInfo(&buf);
+ doc = xml_parse((text *) data, true, true);
- /*
- * FIXME: This is probably supposed to be cleverer if there
- * already is an XML preamble.
- */
- appendStringInfo(&buf,"<?xml");
if (version)
+ doc->version = xmlStrdup(xml_text2xmlChar(version));
+ else
+ doc->version = NULL;
+
+ switch (standalone)
{
- appendStringInfo(&buf, " version=\"");
- appendStringInfoText(&buf, version);
- appendStringInfo(&buf, "\"");
+ case 1:
+ doc->standalone = 1;
+ break;
+ case -1:
+ doc->standalone = 0;
+ break;
+ default:
+ doc->standalone = -1;
+ break;
}
- if (standalone)
- appendStringInfo(&buf, " standalone=\"%s\"",
- (standalone == 1 ? "yes" : "no"));
- appendStringInfo(&buf, "?>");
- appendStringInfoText(&buf, (text *) data);
- result = stringinfo_to_xmltype(&buf);
- pfree(buf.data);
- return result;
+ buffer = xmlBufferCreate();
+ save = xmlSaveToBuffer(buffer, NULL, 0);
+ xmlSaveDoc(save, doc);
+ xmlSaveClose(save);
+
+ xmlFreeDoc(doc);
+
+ return xmlBuffer_to_xmltype(buffer);
#else
NO_XML_SUPPORT();
return NULL;
/* Now that xml_err_buf exists, safe to call xml_errorHandler */
xmlSetGenericErrorFunc(NULL, xml_errorHandler);
+#ifdef NOT_USED
+ /*
+ * FIXME: This doesn't work because libxml assumes that whatever
+ * libxml allocates, only libxml will free, so we can't just drop
+ * memory contexts behind it. This needs to be refined.
+ */
xmlMemSetup(xml_pfree, xml_palloc, xml_repalloc, xml_pstrdup);
+#endif
xmlInitParser();
LIBXML_TEST_VERSION;
}
* ) */
/* ... */
- if (doc)
- xmlFreeDoc(doc);
if (ctxt)
xmlFreeParserCtxt(ctxt);
xmlCleanupParser();
{
if (doc)
xmlFreeDoc(doc);
+ doc = NULL;
if (ctxt)
xmlFreeParserCtxt(ctxt);
xmlCleanupParser();
}
+#ifdef NOT_USED
/*
* Wrappers for memory management functions
*/
{
return pstrdup(string);
}
+#endif /* NOT_USED */
/*
SELECT xmlpi(name foo, 'in?>valid');
ERROR: invalid XML processing instruction
DETAIL: XML processing instruction cannot contain "?>".
+SELECT xmlroot(xml '<foo/>', version no value, standalone no value);
+ xmlroot
+-----------------------
+ <?xml version="1.0"?>
+ <foo/>
+
+(1 row)
+
+SELECT xmlroot(xml '<foo/>', version '2.0');
+ xmlroot
+-----------------------
+ <?xml version="2.0"?>
+ <foo/>
+
+(1 row)
+
+SELECT xmlroot(xmlroot(xml '<foo/>', version '1.0'), version '1.1', standalone no);
+ xmlroot
+---------------------------------------
+ <?xml version="1.1" standalone="no"?>
+ <foo/>
+
+(1 row)
+
SELECT xmlroot (
xmlelement (
name gazonk,
version '1.0',
standalone yes
);
- xmlroot
-------------------------------------------------------------------------------------------
- <?xml version="1.0" standalone="yes"?><gazonk name="val" num="2"><qux>foo</qux></gazonk>
+ xmlroot
+----------------------------------------------------
+ <?xml version="1.0" standalone="yes"?>
+ <gazonk name="val" num="2"><qux>foo</qux></gazonk>
+
(1 row)
SELECT xmlserialize(content data as character varying) FROM xmltest;