@@ -1730,7 +1730,7 @@ xml_doctype_in_content(const xmlChar *str)
1730
1730
* xmloption_arg, but a DOCTYPE node in the input can force DOCUMENT mode).
1731
1731
*
1732
1732
* If parsed_nodes isn't NULL and we parse in CONTENT mode, the list
1733
- * of parsed nodes from the xmlParseInNodeContext call will be returned
1733
+ * of parsed nodes from the xmlParseBalancedChunkMemory call will be returned
1734
1734
* to *parsed_nodes. (It is caller's responsibility to free that.)
1735
1735
*
1736
1736
* Errors normally result in ereport(ERROR), but if escontext is an
@@ -1756,6 +1756,7 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1756
1756
PgXmlErrorContext * xmlerrcxt ;
1757
1757
volatile xmlParserCtxtPtr ctxt = NULL ;
1758
1758
volatile xmlDocPtr doc = NULL ;
1759
+ volatile int save_keep_blanks = -1 ;
1759
1760
1760
1761
/*
1761
1762
* This step looks annoyingly redundant, but we must do it to have a
@@ -1783,7 +1784,6 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1783
1784
PG_TRY ();
1784
1785
{
1785
1786
bool parse_as_document = false;
1786
- int options ;
1787
1787
int res_code ;
1788
1788
size_t count = 0 ;
1789
1789
xmlChar * version = NULL ;
@@ -1814,18 +1814,6 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1814
1814
parse_as_document = true;
1815
1815
}
1816
1816
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
-
1829
1817
/* initialize output parameters */
1830
1818
if (parsed_xmloptiontype != NULL )
1831
1819
* parsed_xmloptiontype = parse_as_document ? XMLOPTION_DOCUMENT :
@@ -1835,11 +1823,26 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1835
1823
1836
1824
if (parse_as_document )
1837
1825
{
1826
+ int options ;
1827
+
1828
+ /* set up parser context used by xmlCtxtReadDoc */
1838
1829
ctxt = xmlNewParserCtxt ();
1839
1830
if (ctxt == NULL || xmlerrcxt -> err_occurred )
1840
1831
xml_ereport (xmlerrcxt , ERROR , ERRCODE_OUT_OF_MEMORY ,
1841
1832
"could not allocate parser context" );
1842
1833
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
+
1843
1846
doc = xmlCtxtReadDoc (ctxt , utf8string ,
1844
1847
NULL , /* no URL */
1845
1848
"UTF-8" ,
@@ -1861,10 +1864,7 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1861
1864
}
1862
1865
else
1863
1866
{
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 */
1868
1868
doc = xmlNewDoc (version );
1869
1869
if (doc == NULL || xmlerrcxt -> err_occurred )
1870
1870
xml_ereport (xmlerrcxt , ERROR , ERRCODE_OUT_OF_MEMORY ,
@@ -1877,36 +1877,23 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1877
1877
"could not allocate XML document" );
1878
1878
doc -> standalone = standalone ;
1879
1879
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 );
1891
1882
1892
1883
/* allow empty content */
1893
1884
if (* (utf8string + count ))
1894
1885
{
1895
1886
xmlNodePtr 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 );
1903
1887
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 )
1905
1892
{
1906
- xmlFreeNodeList (node_list );
1907
1893
xml_errsave (escontext , xmlerrcxt ,
1908
1894
ERRCODE_INVALID_XML_CONTENT ,
1909
1895
"invalid XML content" );
1896
+ xmlFreeNodeList (node_list );
1910
1897
goto fail ;
1911
1898
}
1912
1899
@@ -1922,6 +1909,8 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1922
1909
}
1923
1910
PG_CATCH ();
1924
1911
{
1912
+ if (save_keep_blanks != -1 )
1913
+ xmlKeepBlanksDefault (save_keep_blanks );
1925
1914
if (doc != NULL )
1926
1915
xmlFreeDoc (doc );
1927
1916
if (ctxt != NULL )
@@ -1933,6 +1922,9 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
1933
1922
}
1934
1923
PG_END_TRY ();
1935
1924
1925
+ if (save_keep_blanks != -1 )
1926
+ xmlKeepBlanksDefault (save_keep_blanks );
1927
+
1936
1928
if (ctxt != NULL )
1937
1929
xmlFreeParserCtxt (ctxt );
1938
1930
0 commit comments