@@ -1769,7 +1769,7 @@ xml_doctype_in_content(const xmlChar *str)
17691769 * xmloption_arg, but a DOCTYPE node in the input can force DOCUMENT mode).
17701770 *
17711771 * If parsed_nodes isn't NULL and we parse in CONTENT mode, the list
1772- * of parsed nodes from thexmlParseInNodeContext call will be returned
1772+ * of parsed nodes from thexmlParseBalancedChunkMemory call will be returned
17731773 * to *parsed_nodes. (It is caller's responsibility to free that.)
17741774 *
17751775 * Errors normally result in ereport(ERROR), but if escontext is an
@@ -1795,6 +1795,7 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
17951795PgXmlErrorContext * xmlerrcxt ;
17961796volatile xmlParserCtxtPtr ctxt = NULL ;
17971797volatile xmlDocPtr doc = NULL ;
1798+ volatile int save_keep_blanks = -1 ;
17981799
17991800/*
18001801 * This step looks annoyingly redundant, but we must do it to have a
@@ -1822,7 +1823,6 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
18221823PG_TRY ();
18231824{
18241825bool parse_as_document = false;
1825- int options ;
18261826int res_code ;
18271827size_t count = 0 ;
18281828xmlChar * version = NULL ;
@@ -1853,18 +1853,6 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
18531853parse_as_document = true;
18541854}
18551855
1856- /*
1857- * Select parse options.
1858- *
1859- * Note that here we try to apply DTD defaults (XML_PARSE_DTDATTR)
1860- * according to SQL/XML:2008 GR 10.16.7.d: 'Default values defined by
1861- * internal DTD are applied'. As for external DTDs, we try to support
1862- * them too (see SQL/XML:2008 GR 10.16.7.e), but that doesn't really
1863- * happen because xmlPgEntityLoader prevents it.
1864- */
1865- options = XML_PARSE_NOENT |XML_PARSE_DTDATTR
1866- | (preserve_whitespace ?0 :XML_PARSE_NOBLANKS );
1867-
18681856/* initialize output parameters */
18691857if (parsed_xmloptiontype != NULL )
18701858* parsed_xmloptiontype = parse_as_document ?XMLOPTION_DOCUMENT :
@@ -1874,11 +1862,26 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
18741862
18751863if (parse_as_document )
18761864{
1865+ int options ;
1866+
1867+ /* set up parser context used by xmlCtxtReadDoc */
18771868ctxt = xmlNewParserCtxt ();
18781869if (ctxt == NULL || xmlerrcxt -> err_occurred )
18791870xml_ereport (xmlerrcxt ,ERROR ,ERRCODE_OUT_OF_MEMORY ,
18801871"could not allocate parser context" );
18811872
1873+ /*
1874+ * Select parse options.
1875+ *
1876+ * Note that here we try to apply DTD defaults (XML_PARSE_DTDATTR)
1877+ * according to SQL/XML:2008 GR 10.16.7.d: 'Default values defined
1878+ * by internal DTD are applied'. As for external DTDs, we try to
1879+ * support them too (see SQL/XML:2008 GR 10.16.7.e), but that
1880+ * doesn't really happen because xmlPgEntityLoader prevents it.
1881+ */
1882+ options = XML_PARSE_NOENT |XML_PARSE_DTDATTR
1883+ | (preserve_whitespace ?0 :XML_PARSE_NOBLANKS );
1884+
18821885doc = xmlCtxtReadDoc (ctxt ,utf8string ,
18831886NULL ,/* no URL */
18841887"UTF-8" ,
@@ -1900,10 +1903,7 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
19001903}
19011904else
19021905{
1903- xmlNodePtr root ;
1904- xmlNodePtr oldroot PG_USED_FOR_ASSERTS_ONLY ;
1905-
1906- /* set up document with empty root node to be the context node */
1906+ /* set up document that xmlParseBalancedChunkMemory will add to */
19071907doc = xmlNewDoc (version );
19081908if (doc == NULL || xmlerrcxt -> err_occurred )
19091909xml_ereport (xmlerrcxt ,ERROR ,ERRCODE_OUT_OF_MEMORY ,
@@ -1916,36 +1916,23 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
19161916"could not allocate XML document" );
19171917doc -> standalone = standalone ;
19181918
1919- root = xmlNewNode (NULL , (const xmlChar * )"content-root" );
1920- if (root == NULL || xmlerrcxt -> err_occurred )
1921- xml_ereport (xmlerrcxt ,ERROR ,ERRCODE_OUT_OF_MEMORY ,
1922- "could not allocate xml node" );
1923-
1924- /*
1925- * This attaches root to doc, so we need not free it separately;
1926- * and there can't yet be any old root to free.
1927- */
1928- oldroot = xmlDocSetRootElement (doc ,root );
1929- Assert (oldroot == NULL );
1919+ /* set parse options --- have to do this the ugly way */
1920+ save_keep_blanks = xmlKeepBlanksDefault (preserve_whitespace ?1 :0 );
19301921
19311922/* allow empty content */
19321923if (* (utf8string + count ))
19331924{
19341925xmlNodePtr node_list = NULL ;
1935- xmlParserErrors res ;
1936-
1937- res = xmlParseInNodeContext (root ,
1938- (char * )utf8string + count ,
1939- strlen ((char * )utf8string + count ),
1940- options ,
1941- & node_list );
19421926
1943- if (res != XML_ERR_OK || xmlerrcxt -> err_occurred )
1927+ res_code = xmlParseBalancedChunkMemory (doc ,NULL ,NULL ,0 ,
1928+ utf8string + count ,
1929+ & node_list );
1930+ if (res_code != 0 || xmlerrcxt -> err_occurred )
19441931{
1945- xmlFreeNodeList (node_list );
19461932xml_errsave (escontext ,xmlerrcxt ,
19471933ERRCODE_INVALID_XML_CONTENT ,
19481934"invalid XML content" );
1935+ xmlFreeNodeList (node_list );
19491936gotofail ;
19501937}
19511938
@@ -1961,6 +1948,8 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
19611948}
19621949PG_CATCH ();
19631950{
1951+ if (save_keep_blanks != -1 )
1952+ xmlKeepBlanksDefault (save_keep_blanks );
19641953if (doc != NULL )
19651954xmlFreeDoc (doc );
19661955if (ctxt != NULL )
@@ -1972,6 +1961,9 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
19721961}
19731962PG_END_TRY ();
19741963
1964+ if (save_keep_blanks != -1 )
1965+ xmlKeepBlanksDefault (save_keep_blanks );
1966+
19751967if (ctxt != NULL )
19761968xmlFreeParserCtxt (ctxt );
19771969