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>');