diff options
-rw-r--r-- | src/backend/utils/adt/xml.c | 17 | ||||
-rw-r--r-- | src/test/regress/expected/xml.out | 15 | ||||
-rw-r--r-- | src/test/regress/expected/xml_1.out | 12 | ||||
-rw-r--r-- | src/test/regress/sql/xml.sql | 2 |
4 files changed, 45 insertions, 1 deletions
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index bfaf0a0be70..bcf058d9c3c 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -3286,19 +3286,34 @@ xml_xmlnodetoxmltype(xmlNodePtr cur) if (cur->type == XML_ELEMENT_NODE) { xmlBufferPtr buf; + xmlNodePtr cur_copy; buf = xmlBufferCreate(); + + /* + * The result of xmlNodeDump() won't contain namespace definitions + * from parent nodes, but xmlCopyNode() duplicates a node along with + * its required namespace definitions. + */ + cur_copy = xmlCopyNode(cur, 1); + + if (cur_copy == NULL) + xml_ereport(ERROR, ERRCODE_OUT_OF_MEMORY, + "could not copy node"); + PG_TRY(); { - xmlNodeDump(buf, NULL, cur, 0, 1); + xmlNodeDump(buf, NULL, cur_copy, 0, 1); result = xmlBuffer_to_xmltype(buf); } PG_CATCH(); { + xmlFreeNode(cur_copy); xmlBufferFree(buf); PG_RE_THROW(); } PG_END_TRY(); + xmlFreeNode(cur_copy); xmlBufferFree(buf); } else diff --git a/src/test/regress/expected/xml.out b/src/test/regress/expected/xml.out index b6ec98502b7..a236afd04b3 100644 --- a/src/test/regress/expected/xml.out +++ b/src/test/regress/expected/xml.out @@ -496,6 +496,21 @@ SELECT xpath('//loc:piece/@id', '<local:data xmlns:local="http://127.0.0.1"><loc {1,2} (1 row) +SELECT xpath('//loc:piece', '<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', 'http://127.0.0.1']]); + xpath +------------------------------------------------------------------------------------------------------------------------------------------------ + {"<local:piece xmlns:local=\"http://127.0.0.1\" id=\"1\">number one</local:piece>","<local:piece xmlns:local=\"http://127.0.0.1\" id=\"2\"/>"} +(1 row) + +SELECT xpath('//loc:piece', '<local:data xmlns:local="http://127.0.0.1" xmlns="http://127.0.0.2"><local:piece id="1"><internal>number one</internal><internal2/></local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); + xpath +-------------------------------------------------------------------------------------- + {"<local:piece xmlns:local=\"http://127.0.0.1\" xmlns=\"http://127.0.0.2\" id=\"1\">+ + <internal>number one</internal> + + <internal2/> + + </local:piece>","<local:piece xmlns:local=\"http://127.0.0.1\" id=\"2\"/>"} +(1 row) + SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>'); xpath ------------------------- diff --git a/src/test/regress/expected/xml_1.out b/src/test/regress/expected/xml_1.out index 38a98ad3216..abff7a5f635 100644 --- a/src/test/regress/expected/xml_1.out +++ b/src/test/regress/expected/xml_1.out @@ -450,6 +450,18 @@ LINE 1: SELECT xpath('//loc:piece/@id', '<local:data xmlns:local="ht... ^ DETAIL: This functionality requires the server to be built with libxml support. HINT: You need to rebuild PostgreSQL using --with-libxml. +SELECT xpath('//loc:piece', '<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', 'http://127.0.0.1']]); +ERROR: unsupported XML feature +LINE 1: SELECT xpath('//loc:piece', '<local:data xmlns:local="http:/... + ^ +DETAIL: This functionality requires the server to be built with libxml support. +HINT: You need to rebuild PostgreSQL using --with-libxml. +SELECT xpath('//loc:piece', '<local:data xmlns:local="http://127.0.0.1" xmlns="http://127.0.0.2"><local:piece id="1"><internal>number one</internal><internal2/></local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); +ERROR: unsupported XML feature +LINE 1: SELECT xpath('//loc:piece', '<local:data xmlns:local="http:/... + ^ +DETAIL: This functionality requires the server to be built with libxml support. +HINT: You need to rebuild PostgreSQL using --with-libxml. SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>'); ERROR: unsupported XML feature LINE 1: SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>'... diff --git a/src/test/regress/sql/xml.sql b/src/test/regress/sql/xml.sql index 366e2798d40..c7ceeb168e8 100644 --- a/src/test/regress/sql/xml.sql +++ b/src/test/regress/sql/xml.sql @@ -162,6 +162,8 @@ SELECT xpath(NULL, NULL) IS NULL FROM xmltest; SELECT xpath('', '<!-- error -->'); SELECT xpath('//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 xpath('//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', 'http://127.0.0.1']]); +SELECT xpath('//loc:piece', '<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', 'http://127.0.0.1']]); +SELECT xpath('//loc:piece', '<local:data xmlns:local="http://127.0.0.1" xmlns="http://127.0.0.2"><local:piece id="1"><internal>number one</internal><internal2/></local:piece><local:piece id="2" /></local:data>', ARRAY[ARRAY['loc', 'http://127.0.0.1']]); SELECT xpath('//b', '<a>one <b>two</b> three <b>etc</b></a>'); -- Test xmlexists and xpath_exists |