@@ -1769,7 +1769,7 @@ xml_doctype_in_content(const xmlChar *str)
1769
1769
* xmloption_arg, but a DOCTYPE node in the input can force DOCUMENT mode).
1770
1770
*
1771
1771
* If parsed_nodes isn't NULL and we parse in CONTENT mode, the list
1772
- * of parsed nodes from the xmlParseInNodeContext call will be returned
1772
+ * of parsed nodes from the xmlParseBalancedChunkMemory call will be returned
1773
1773
* to *parsed_nodes. (It is caller's responsibility to free that.)
1774
1774
*
1775
1775
* Errors normally result in ereport(ERROR), but if escontext is an
@@ -1795,6 +1795,7 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1795
1795
PgXmlErrorContext * xmlerrcxt ;
1796
1796
volatile xmlParserCtxtPtr ctxt = NULL ;
1797
1797
volatile xmlDocPtr doc = NULL ;
1798
+ volatile int save_keep_blanks = -1 ;
1798
1799
1799
1800
/*
1800
1801
* This step looks annoyingly redundant, but we must do it to have a
@@ -1822,7 +1823,6 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1822
1823
PG_TRY ();
1823
1824
{
1824
1825
bool parse_as_document = false;
1825
- int options ;
1826
1826
int res_code ;
1827
1827
size_t count = 0 ;
1828
1828
xmlChar * version = NULL ;
@@ -1853,18 +1853,6 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1853
1853
parse_as_document = true;
1854
1854
}
1855
1855
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
-
1868
1856
/* initialize output parameters */
1869
1857
if (parsed_xmloptiontype != NULL )
1870
1858
* parsed_xmloptiontype = parse_as_document ? XMLOPTION_DOCUMENT :
@@ -1874,11 +1862,26 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1874
1862
1875
1863
if (parse_as_document )
1876
1864
{
1865
+ int options ;
1866
+
1867
+ /* set up parser context used by xmlCtxtReadDoc */
1877
1868
ctxt = xmlNewParserCtxt ();
1878
1869
if (ctxt == NULL || xmlerrcxt -> err_occurred )
1879
1870
xml_ereport (xmlerrcxt , ERROR , ERRCODE_OUT_OF_MEMORY ,
1880
1871
"could not allocate parser context" );
1881
1872
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
+
1882
1885
doc = xmlCtxtReadDoc (ctxt , utf8string ,
1883
1886
NULL , /* no URL */
1884
1887
"UTF-8" ,
@@ -1900,10 +1903,7 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1900
1903
}
1901
1904
else
1902
1905
{
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 */
1907
1907
doc = xmlNewDoc (version );
1908
1908
if (doc == NULL || xmlerrcxt -> err_occurred )
1909
1909
xml_ereport (xmlerrcxt , ERROR , ERRCODE_OUT_OF_MEMORY ,
@@ -1916,36 +1916,23 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1916
1916
"could not allocate XML document" );
1917
1917
doc -> standalone = standalone ;
1918
1918
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 );
1930
1921
1931
1922
/* allow empty content */
1932
1923
if (* (utf8string + count ))
1933
1924
{
1934
1925
xmlNodePtr 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 );
1942
1926
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 )
1944
1931
{
1945
- xmlFreeNodeList (node_list );
1946
1932
xml_errsave (escontext , xmlerrcxt ,
1947
1933
ERRCODE_INVALID_XML_CONTENT ,
1948
1934
"invalid XML content" );
1935
+ xmlFreeNodeList (node_list );
1949
1936
goto fail ;
1950
1937
}
1951
1938
@@ -1961,6 +1948,8 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1961
1948
}
1962
1949
PG_CATCH ();
1963
1950
{
1951
+ if (save_keep_blanks != -1 )
1952
+ xmlKeepBlanksDefault (save_keep_blanks );
1964
1953
if (doc != NULL )
1965
1954
xmlFreeDoc (doc );
1966
1955
if (ctxt != NULL )
@@ -1972,6 +1961,9 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1972
1961
}
1973
1962
PG_END_TRY ();
1974
1963
1964
+ if (save_keep_blanks != -1 )
1965
+ xmlKeepBlanksDefault (save_keep_blanks );
1966
+
1975
1967
if (ctxt != NULL )
1976
1968
xmlFreeParserCtxt (ctxt );
1977
1969
0 commit comments