From ea3b212feee894ebbb5ae36eabc8273b59674cad Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Thu, 22 Mar 2007 20:26:30 +0000 Subject: [PATCH] Commit newest version of xmlpath(). Nikolay Samokhvalov --- src/backend/utils/adt/xml.c | 37 ++++++++++++++++++++++++------------- src/test/regress/expected/xml.out | 14 ++++++++++---- src/test/regress/expected/xml_1.out | 2 ++ src/test/regress/sql/xml.sql | 1 + 4 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index 00f661df9d..e9c9496801 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.36 2007/03/22 20:14:58 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.37 2007/03/22 20:26:30 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -91,7 +91,7 @@ static xmlChar *xml_text2xmlChar(text *in); static int parse_xml_decl(const xmlChar *str, size_t *lenp, xmlChar **version, xmlChar **encoding, int *standalone); static bool print_xml_decl(StringInfo buf, const xmlChar *version, pg_enc encoding, int standalone); static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace, xmlChar *encoding); -static text *xml_xmlnodetotext(xmlNodePtr cur); +static text *xml_xmlnodetoxmltype(xmlNodePtr cur); #endif /* USE_LIBXML */ @@ -2414,20 +2414,31 @@ SPI_sql_row_to_xmlelement(int rownum, StringInfo result, char *tablename, bool n #ifdef USE_LIBXML /* - * Convert XML node to text (return value only, it's not dumping) + * Convert XML node to text (dump subtree in case of element, return value otherwise) */ text * -xml_xmlnodetotext(xmlNodePtr cur) +xml_xmlnodetoxmltype(xmlNodePtr cur) { - xmlChar *str; - text *result; - size_t len; + xmlChar *str; + xmltype *result; + size_t len; + xmlBufferPtr buf; - str = xmlXPathCastNodeToString(cur); - len = strlen((char *) str); - result = (text *) palloc(len + VARHDRSZ); - SET_VARSIZE(result, len + VARHDRSZ); - memcpy(VARDATA(result), str, len); + if (cur->type == XML_ELEMENT_NODE) + { + buf = xmlBufferCreate(); + xmlNodeDump(buf, NULL, cur, 0, 1); + result = xmlBuffer_to_xmltype(buf); + xmlBufferFree(buf); + } + else + { + str = xmlXPathCastNodeToString(cur); + len = strlen((char *) str); + result = (text *) palloc(len + VARHDRSZ); + SET_VARSIZE(result, len + VARHDRSZ); + memcpy(VARDATA(result), str, len); + } return result; } @@ -2607,7 +2618,7 @@ xmlpath(PG_FUNCTION_ARGS) { Datum elem; bool elemisnull = false; - elem = PointerGetDatum(xml_xmlnodetotext(xpathobj->nodesetval->nodeTab[i])); + elem = PointerGetDatum(xml_xmlnodetoxmltype(xpathobj->nodesetval->nodeTab[i])); astate = accumArrayResult(astate, elem, elemisnull, XMLOID, CurrentMemoryContext); diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out index 189c22113b..20520d9760 100644 --- a/src/test/regress/expected/xml.out +++ b/src/test/regress/expected/xml.out @@ -403,10 +403,10 @@ SELECT table_name, view_definition FROM information_schema.views -- Text XPath expressions evaluation SELECT xmlpath('/value', data) FROM xmltest; - xmlpath ---------- - {one} - {two} + xmlpath +---------------------- + {one} + {two} (2 rows) SELECT xmlpath(NULL, NULL) IS NULL FROM xmltest; @@ -431,3 +431,9 @@ SELECT xmlpath('//loc:piece/@id', 'one two three etc'); + xmlpath +------------------------- + {two,etc} +(1 row) + diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out index 3ba6e58d2d..3709088dfd 100644 --- a/src/test/regress/expected/xml_1.out +++ b/src/test/regress/expected/xml_1.out @@ -212,3 +212,5 @@ SELECT xmlpath('//text()', 'number one', ARRAY[ARRAY['loc'], ARRAY['http://127.0.0.1']]); ERROR: no XML support in this installation +SELECT xmlpath('//b', 'one two three etc'); +ERROR: no XML support in this installation diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql index 32ac15610c..1658a38036 100644 --- a/src/test/regress/sql/xml.sql +++ b/src/test/regress/sql/xml.sql @@ -152,3 +152,4 @@ SELECT xmlpath(NULL, NULL) IS NULL FROM xmltest; SELECT xmlpath('', ''); SELECT xmlpath('//text()', 'number one'); SELECT xmlpath('//loc:piece/@id', 'number one', ARRAY[ARRAY['loc'], ARRAY['http://127.0.0.1']]); +SELECT xmlpath('//b', 'one two three etc'); -- 2.11.0