Commit newest version of xmlpath().
authorBruce Momjian <bruce@momjian.us>
Thu, 22 Mar 2007 20:26:30 +0000 (20:26 +0000)
committerBruce Momjian <bruce@momjian.us>
Thu, 22 Mar 2007 20:26:30 +0000 (20:26 +0000)
Nikolay Samokhvalov

src/backend/utils/adt/xml.c
src/test/regress/expected/xml.out
src/test/regress/expected/xml_1.out
src/test/regress/sql/xml.sql

index 00f661df9d4fae699690888186fa10eec9e91386..e9c94968011bb1c69531c03f907914d6b6ff00cf 100644 (file)
@@ -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);
index 189c22113b3bdf32b8a165ec20a07e429c35aded..20520d97606a2ac789d56d48063a2f81366d056a 100644 (file)
@@ -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)
+
index 3ba6e58d2d8fde59904d25d8f280dda1e1d3113d..3709088dfd9a019e882c77d4d60214e8914e834f 100644 (file)
@@ -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
index 32ac15610c74ce3039b0d79888f35f04f82b7867..1658a3803650f772bc01c2109c478fe1f66a5592 100644 (file)
@@ -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>');