diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index 00f661df9d4fae699690888186fa10eec9e91386..e9c94968011bb1c69531c03f907914d6b6ff00cf 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 189c22113b3bdf32b8a165ec20a07e429c35aded..20520d97606a2ac789d56d48063a2f81366d056a 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 +---------------------- + {<value>one</value>} + {<value>two</value>} (2 rows) SELECT xmlpath(NULL, NULL) IS NULL FROM xmltest; @@ -431,3 +431,9 @@ SELECT xmlpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><l {1,2} (1 row) +SELECT xmlpath('//b', '<a>one <b>two</b> three <b>etc</b></a>'); + xmlpath +------------------------- + {<b>two</b>,<b>etc</b>} +(1 row) + diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out index 3ba6e58d2d8fde59904d25d8f280dda1e1d3113d..3709088dfd9a019e882c77d4d60214e8914e834f 100644 --- a/src/test/regress/expected/xml_1.out +++ b/src/test/regress/expected/xml_1.out @@ -212,3 +212,5 @@ SELECT xmlpath('//text()', '<local:data xmlns:local="http://127.0.0.1"><local:pi ERROR: no XML support in this installation SELECT xmlpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc'], ARRAY['http://127.0.0.1']]); ERROR: no XML support in this installation +SELECT xmlpath('//b', '<a>one <b>two</b> three <b>etc</b></a>'); +ERROR: no XML support in this installation diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql index 32ac15610c74ce3039b0d79888f35f04f82b7867..1658a3803650f772bc01c2109c478fe1f66a5592 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('', '<!-- error -->'); SELECT xmlpath('//text()', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>'); SELECT xmlpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><local:piece id="1">number one</local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc'], ARRAY['http://127.0.0.1']]); +SELECT xmlpath('//b', '<a>one <b>two</b> three <b>etc</b></a>');