diff --git a/contrib/xml2/xpath.c b/contrib/xml2/xpath.c
index 1ce031fa37f49da6739948c5869b414bdc6477c9..5fcfa7b1e184366f1c71cc3ce5778ead6c8ad237 100644
--- a/contrib/xml2/xpath.c
+++ b/contrib/xml2/xpath.c
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/xml2/xpath.c,v 1.28 2010/03/01 05:16:35 tgl Exp $
+ * $PostgreSQL: pgsql/contrib/xml2/xpath.c,v 1.29 2010/03/03 19:10:22 tgl Exp $
  *
  * Parser interface for DOM-based parser (libxml) rather than
  * stream-based SAX-type parser
@@ -12,6 +12,7 @@
 #include "lib/stringinfo.h"
 #include "miscadmin.h"
 #include "utils/builtins.h"
+#include "utils/xml.h"
 
 /* libxml includes */
 
@@ -35,15 +36,12 @@ Datum		xpath_bool(PG_FUNCTION_ARGS);
 Datum		xpath_list(PG_FUNCTION_ARGS);
 Datum		xpath_table(PG_FUNCTION_ARGS);
 
-/* these are exported for use by xslt_proc.c */
+/* exported for use by xslt_proc.c */
 
-void		elog_error(const char *explain, bool force);
 void		pgxml_parser_init(void);
 
 /* local declarations */
 
-static void pgxml_errorHandler(void *ctxt, const char *msg,...);
-
 static xmlChar *pgxmlNodeSetToText(xmlNodeSetPtr nodeset,
 				   xmlChar *toptagname, xmlChar *septagname,
 				   xmlChar *plainsep);
@@ -55,62 +53,6 @@ static xmlChar *pgxml_texttoxmlchar(text *textstring);
 
 static xmlXPathObjectPtr pgxml_xpath(text *document, xmlChar *xpath);
 
-/* Global variables */
-static char *pgxml_errorMsg = NULL;		/* overall error message */
-
-
-/*
- * The error handling function. This formats an error message and sets
- * a flag - an ereport will be issued prior to return
- */
-static void
-pgxml_errorHandler(void *ctxt, const char *msg,...)
-{
-	char		errbuf[1024];				/* per line error buffer */
-	va_list		args;
-
-	/* Format the message */
-	va_start(args, msg);
-	vsnprintf(errbuf, sizeof(errbuf), msg, args);
-	va_end(args);
-	/* Store in, or append to, pgxml_errorMsg */
-	if (pgxml_errorMsg == NULL)
-		pgxml_errorMsg = pstrdup(errbuf);
-	else
-	{
-		size_t	oldsize = strlen(pgxml_errorMsg);
-		size_t	newsize = strlen(errbuf);
-
-		/*
-		 * We intentionally discard the last char of the existing message,
-		 * which should be a carriage return.  (XXX wouldn't it be saner
-		 * to keep it?)
-		 */
-		pgxml_errorMsg = repalloc(pgxml_errorMsg, oldsize + newsize);
-		memcpy(&pgxml_errorMsg[oldsize - 1], errbuf, newsize);
-		pgxml_errorMsg[oldsize + newsize - 1] = '\0';
-	}
-}
-
-/*
- * This function ereports the current message if any.  If force is true
- * then an error is thrown even if pgxml_errorMsg hasn't been set.
- */
-void
-elog_error(const char *explain, bool force)
-{
-	if (force || pgxml_errorMsg != NULL)
-	{
-		if (pgxml_errorMsg == NULL)
-			ereport(ERROR,
-					(errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
-					 errmsg("%s", explain)));
-		else
-			ereport(ERROR,
-					(errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
-					 errmsg("%s: %s", explain, pgxml_errorMsg)));
-	}
-}
 
 /*
  * Initialize for xml parsing.
@@ -118,9 +60,8 @@ elog_error(const char *explain, bool force)
 void
 pgxml_parser_init(void)
 {
-	/* Set up error handling */
-	pgxml_errorMsg = NULL;
-	xmlSetGenericErrorFunc(NULL, pgxml_errorHandler);
+	/* Set up error handling (we share the core's error handler) */
+	pg_xml_init();
 
 	/* Initialize libxml */
 	xmlInitParser();
@@ -466,7 +407,8 @@ pgxml_xpath(text *document, xmlChar *xpath)
 	if (comppath == NULL)
 	{
 		xmlFreeDoc(doctree);
-		elog_error("XPath Syntax Error", true);
+		xml_ereport(ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
+					"XPath Syntax Error");
 	}
 
 	/* Now evaluate the path expression. */
@@ -519,8 +461,6 @@ pgxml_result_to_text(xmlXPathObjectPtr res,
 	/* Free various storage */
 	xmlFree(xpresstr);
 
-	elog_error("XPath error", false);
-
 	return xpres;
 }
 
@@ -691,10 +631,8 @@ xpath_table(PG_FUNCTION_ARGS)
 	}
 
 	/*
-	 * Setup the parser. Beware that this must happen in the same context as
-	 * the cleanup - which means that any error from here on must do cleanup
-	 * to ensure that the entity table doesn't get freed by being out of
-	 * context.
+	 * Setup the parser.  This should happen after we are done evaluating
+	 * the query, in case it calls functions that set up libxml differently.
 	 */
 	pgxml_parser_init();
 
@@ -751,14 +689,14 @@ xpath_table(PG_FUNCTION_ARGS)
 				{
 					ctxt = xmlXPathNewContext(doctree);
 					ctxt->node = xmlDocGetRootElement(doctree);
-					xmlSetGenericErrorFunc(ctxt, pgxml_errorHandler);
 
 					/* compile the path */
 					comppath = xmlXPathCompile(xpaths[j]);
 					if (comppath == NULL)
 					{
 						xmlFreeDoc(doctree);
-						elog_error("XPath Syntax Error", true);
+						xml_ereport(ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
+									"XPath Syntax Error");
 					}
 
 					/* Now evaluate the path expression. */
diff --git a/contrib/xml2/xslt_proc.c b/contrib/xml2/xslt_proc.c
index 9b71766fcebd8275637278a730835c45bf582f4a..8bd9e401fa20a1a744518e3aac2590cc03414b05 100644
--- a/contrib/xml2/xslt_proc.c
+++ b/contrib/xml2/xslt_proc.c
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/contrib/xml2/xslt_proc.c,v 1.19 2010/03/01 18:07:59 tgl Exp $
+ * $PostgreSQL: pgsql/contrib/xml2/xslt_proc.c,v 1.20 2010/03/03 19:10:22 tgl Exp $
  *
  * XSLT processing functions (requiring libxslt)
  *
@@ -12,6 +12,7 @@
 #include "funcapi.h"
 #include "miscadmin.h"
 #include "utils/builtins.h"
+#include "utils/xml.h"
 
 #ifdef USE_LIBXSLT
 
@@ -38,7 +39,6 @@ Datum		xslt_process(PG_FUNCTION_ARGS);
 #ifdef USE_LIBXSLT
 
 /* declarations to come from xpath.c */
-extern void elog_error(const char *explain, bool force);
 extern void pgxml_parser_init(void);
 
 /* local defs */
@@ -88,11 +88,8 @@ xslt_process(PG_FUNCTION_ARGS)
 		doctree = xmlParseFile(text_to_cstring(doct));
 
 	if (doctree == NULL)
-	{
-		elog_error("error parsing XML document", false);
-
-		PG_RETURN_NULL();
-	}
+		xml_ereport(ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
+					"error parsing XML document");
 
 	/* Same for stylesheet */
 	if (VARDATA(ssheet)[0] == '<')
@@ -102,8 +99,8 @@ xslt_process(PG_FUNCTION_ARGS)
 		if (ssdoc == NULL)
 		{
 			xmlFreeDoc(doctree);
-			elog_error("error parsing stylesheet as XML document", false);
-			PG_RETURN_NULL();
+			xml_ereport(ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
+						"error parsing stylesheet as XML document");
 		}
 
 		stylesheet = xsltParseStylesheetDoc(ssdoc);
@@ -116,8 +113,8 @@ xslt_process(PG_FUNCTION_ARGS)
 	{
 		xmlFreeDoc(doctree);
 		xsltCleanupGlobals();
-		elog_error("failed to parse stylesheet", false);
-		PG_RETURN_NULL();
+		xml_ereport(ERROR, ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
+					"failed to parse stylesheet");
 	}
 
 	restree = xsltApplyStylesheet(stylesheet, doctree, params);