@@ -1730,7 +1730,7 @@ xml_doctype_in_content(const xmlChar *str)
17301730 * xmloption_arg, but a DOCTYPE node in the input can force DOCUMENT mode).
17311731 *
17321732 * If parsed_nodes isn't NULL and we parse in CONTENT mode, the list
1733- * of parsed nodes from thexmlParseInNodeContext call will be returned
1733+ * of parsed nodes from thexmlParseBalancedChunkMemory call will be returned
17341734 * to *parsed_nodes. (It is caller's responsibility to free that.)
17351735 *
17361736 * Errors normally result in ereport(ERROR), but if escontext is an
@@ -1756,6 +1756,7 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
17561756PgXmlErrorContext * xmlerrcxt ;
17571757volatile xmlParserCtxtPtr ctxt = NULL ;
17581758volatile xmlDocPtr doc = NULL ;
1759+ volatile int save_keep_blanks = -1 ;
17591760
17601761/*
17611762 * This step looks annoyingly redundant, but we must do it to have a
@@ -1783,7 +1784,6 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
17831784PG_TRY ();
17841785{
17851786bool parse_as_document = false;
1786- int options ;
17871787int res_code ;
17881788size_t count = 0 ;
17891789xmlChar * version = NULL ;
@@ -1814,18 +1814,6 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
18141814parse_as_document = true;
18151815}
18161816
1817- /*
1818- * Select parse options.
1819- *
1820- * Note that here we try to apply DTD defaults (XML_PARSE_DTDATTR)
1821- * according to SQL/XML:2008 GR 10.16.7.d: 'Default values defined by
1822- * internal DTD are applied'. As for external DTDs, we try to support
1823- * them too (see SQL/XML:2008 GR 10.16.7.e), but that doesn't really
1824- * happen because xmlPgEntityLoader prevents it.
1825- */
1826- options = XML_PARSE_NOENT |XML_PARSE_DTDATTR
1827- | (preserve_whitespace ?0 :XML_PARSE_NOBLANKS );
1828-
18291817/* initialize output parameters */
18301818if (parsed_xmloptiontype != NULL )
18311819* parsed_xmloptiontype = parse_as_document ?XMLOPTION_DOCUMENT :
@@ -1835,11 +1823,26 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
18351823
18361824if (parse_as_document )
18371825{
1826+ int options ;
1827+
1828+ /* set up parser context used by xmlCtxtReadDoc */
18381829ctxt = xmlNewParserCtxt ();
18391830if (ctxt == NULL || xmlerrcxt -> err_occurred )
18401831xml_ereport (xmlerrcxt ,ERROR ,ERRCODE_OUT_OF_MEMORY ,
18411832"could not allocate parser context" );
18421833
1834+ /*
1835+ * Select parse options.
1836+ *
1837+ * Note that here we try to apply DTD defaults (XML_PARSE_DTDATTR)
1838+ * according to SQL/XML:2008 GR 10.16.7.d: 'Default values defined
1839+ * by internal DTD are applied'. As for external DTDs, we try to
1840+ * support them too (see SQL/XML:2008 GR 10.16.7.e), but that
1841+ * doesn't really happen because xmlPgEntityLoader prevents it.
1842+ */
1843+ options = XML_PARSE_NOENT |XML_PARSE_DTDATTR
1844+ | (preserve_whitespace ?0 :XML_PARSE_NOBLANKS );
1845+
18431846doc = xmlCtxtReadDoc (ctxt ,utf8string ,
18441847NULL ,/* no URL */
18451848"UTF-8" ,
@@ -1861,10 +1864,7 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
18611864}
18621865else
18631866{
1864- xmlNodePtr root ;
1865- xmlNodePtr oldroot PG_USED_FOR_ASSERTS_ONLY ;
1866-
1867- /* set up document with empty root node to be the context node */
1867+ /* set up document that xmlParseBalancedChunkMemory will add to */
18681868doc = xmlNewDoc (version );
18691869if (doc == NULL || xmlerrcxt -> err_occurred )
18701870xml_ereport (xmlerrcxt ,ERROR ,ERRCODE_OUT_OF_MEMORY ,
@@ -1877,36 +1877,23 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
18771877"could not allocate XML document" );
18781878doc -> standalone = standalone ;
18791879
1880- root = xmlNewNode (NULL , (const xmlChar * )"content-root" );
1881- if (root == NULL || xmlerrcxt -> err_occurred )
1882- xml_ereport (xmlerrcxt ,ERROR ,ERRCODE_OUT_OF_MEMORY ,
1883- "could not allocate xml node" );
1884-
1885- /*
1886- * This attaches root to doc, so we need not free it separately;
1887- * and there can't yet be any old root to free.
1888- */
1889- oldroot = xmlDocSetRootElement (doc ,root );
1890- Assert (oldroot == NULL );
1880+ /* set parse options --- have to do this the ugly way */
1881+ save_keep_blanks = xmlKeepBlanksDefault (preserve_whitespace ?1 :0 );
18911882
18921883/* allow empty content */
18931884if (* (utf8string + count ))
18941885{
18951886xmlNodePtr node_list = NULL ;
1896- xmlParserErrors res ;
1897-
1898- res = xmlParseInNodeContext (root ,
1899- (char * )utf8string + count ,
1900- strlen ((char * )utf8string + count ),
1901- options ,
1902- & node_list );
19031887
1904- if (res != XML_ERR_OK || xmlerrcxt -> err_occurred )
1888+ res_code = xmlParseBalancedChunkMemory (doc ,NULL ,NULL ,0 ,
1889+ utf8string + count ,
1890+ & node_list );
1891+ if (res_code != 0 || xmlerrcxt -> err_occurred )
19051892{
1906- xmlFreeNodeList (node_list );
19071893xml_errsave (escontext ,xmlerrcxt ,
19081894ERRCODE_INVALID_XML_CONTENT ,
19091895"invalid XML content" );
1896+ xmlFreeNodeList (node_list );
19101897gotofail ;
19111898}
19121899
@@ -1922,6 +1909,8 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
19221909}
19231910PG_CATCH ();
19241911{
1912+ if (save_keep_blanks != -1 )
1913+ xmlKeepBlanksDefault (save_keep_blanks );
19251914if (doc != NULL )
19261915xmlFreeDoc (doc );
19271916if (ctxt != NULL )
@@ -1933,6 +1922,9 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
19331922}
19341923PG_END_TRY ();
19351924
1925+ if (save_keep_blanks != -1 )
1926+ xmlKeepBlanksDefault (save_keep_blanks );
1927+
19361928if (ctxt != NULL )
19371929xmlFreeParserCtxt (ctxt );
19381930