diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2006-12-28 03:17:38 +0000 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2006-12-28 03:17:38 +0000 |
commit | d9e1c97feb47a6f61707282133c4546fb682a5a8 (patch) | |
tree | 4d857ec41e741d573c15974ce2cf974b38732799 /src/backend/utils/adt/xml.c | |
parent | 859b8dd51a0f4e5b7c9abe749cb83bffa7f11ce2 (diff) | |
download | postgresql-d9e1c97feb47a6f61707282133c4546fb682a5a8.tar.gz postgresql-d9e1c97feb47a6f61707282133c4546fb682a5a8.zip |
Handle content and document options in xmlparse() correctly.
Diffstat (limited to 'src/backend/utils/adt/xml.c')
-rw-r--r-- | src/backend/utils/adt/xml.c | 93 |
1 files changed, 27 insertions, 66 deletions
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index 7babc82551c..83704f6c794 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.5 2006/12/24 18:25:58 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.6 2006/12/28 03:17:38 petere Exp $ * *------------------------------------------------------------------------- */ @@ -58,7 +58,7 @@ static void xml_errorHandler(void *ctxt, const char *msg, ...); static void xml_ereport_by_code(int level, int sqlcode, const char *msg, int errcode); static xmlChar *xml_text2xmlChar(text *in); -static xmlDocPtr xml_parse(text *data, int opts, bool is_document); +static xmlDocPtr xml_parse(text *data, bool is_document, bool preserve_whitespace); #endif /* USE_LIBXML */ @@ -86,7 +86,7 @@ xml_in(PG_FUNCTION_ARGS) * that ERROR occurred if parsing failed. Do we need DTD * validation (if DTD exists)? */ - xml_parse(vardata, XML_PARSE_DTDATTR | XML_PARSE_DTDVALID, false); + xml_parse(vardata, false, true); PG_RETURN_XML_P(vardata); #else @@ -179,18 +179,7 @@ xmltype * xmlparse(text *data, bool is_document, bool preserve_whitespace) { #ifdef USE_LIBXML - if (!preserve_whitespace) - ereport(WARNING, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("XMLPARSE with STRIP WHITESPACE is not implemented"))); - - /* - * Note, that here we try to apply DTD defaults - * (XML_PARSE_DTDATTR) according to SQL/XML:10.16.7.d: 'Default - * valies defined by internal DTD are applied'. As for external - * DTDs, we try to support them too, (see SQL/XML:10.16.7.e) - */ - xml_parse(data, XML_PARSE_DTDATTR, is_document); + xml_parse(data, is_document, preserve_whitespace); return (xmltype *) data; #else @@ -421,27 +410,18 @@ xml_init(void) /* * Convert a C string to XML internal representation - * (same things as for TEXT, but with checking the data for well-formedness - * and, moreover, validation against DTD, if needed). - * NOTICE: We use TEXT type as internal storage type. In the future, - * we plan to create own storage type (maybe several types/strategies) - * TODO predefined DTDs / XSDs and validation - * TODO validation against XML Schema + * * TODO maybe, libxml2's xmlreader is better? (do not construct DOM, yet do not use SAX - see xml_reader.c) * TODO what about internal URI for docs? (see PG_XML_DEFAULT_URI below) */ static xmlDocPtr -xml_parse(text *data, int opts, bool is_document) +xml_parse(text *data, bool is_document, bool preserve_whitespace) { - bool validationFailed = false; int res_code; int32 len; xmlChar *string; xmlParserCtxtPtr ctxt = NULL; xmlDocPtr doc = NULL; -#ifdef XML_DEBUG_DTD_CONST - xmlDtdPtr dtd = NULL; -#endif len = VARSIZE(data) - VARHDRSZ; /* will be useful later */ string = xml_text2xmlChar(data); @@ -456,51 +436,40 @@ xml_parse(text *data, int opts, bool is_document) xml_ereport(ERROR, ERRCODE_INTERNAL_ERROR, "could not allocate parser context", ctxt); - /* first, we try to parse the string as XML doc, then, as XML chunk */ - if (len >= 5 && strncmp((char *) string, "<?xml", 5) == 0) + if (is_document) { - /* consider it as DOCUMENT */ + /* + * Note, that here we try to apply DTD defaults + * (XML_PARSE_DTDATTR) according to SQL/XML:10.16.7.d: + * 'Default valies defined by internal DTD are applied'. + * As for external DTDs, we try to support them too, (see + * SQL/XML:10.16.7.e) + */ doc = xmlCtxtReadMemory(ctxt, (char *) string, len, - PG_XML_DEFAULT_URI, NULL, opts); + PG_XML_DEFAULT_URI, NULL, + XML_PARSE_NOENT | XML_PARSE_DTDATTR + | (preserve_whitespace ? 0 : XML_PARSE_NOBLANKS)); if (doc == NULL) xml_ereport(ERROR, ERRCODE_INVALID_XML_DOCUMENT, - "could not parse XML data", ctxt); + "invalid XML document", ctxt); } else { - /* attempt to parse the string as if it is an XML fragment */ doc = xmlNewDoc(NULL); + + /* + * FIXME: An XMLDecl is supposed to be accepted before the + * content, but libxml doesn't allow this. Parse that + * ourselves? + */ + /* TODO resolve: xmlParseBalancedChunkMemory assumes that string is UTF8 encoded! */ res_code = xmlParseBalancedChunkMemory(doc, NULL, NULL, 0, string, NULL); if (res_code != 0) - xml_ereport_by_code(ERROR, ERRCODE_INVALID_XML_DOCUMENT, - "could not parse XML data", res_code); + xml_ereport_by_code(ERROR, ERRCODE_INVALID_XML_CONTENT, + "invalid XML content", res_code); } -#ifdef XML_DEBUG_DTD_CONST - dtd = xmlParseDTD(NULL, (xmlChar *) XML_DEBUG_DTD_CONST); - if (dtd == NULL) - xml_ereport(ERROR, ERRCODE_INVALID_XML_DOCUMENT, - "could not parse DTD data", ctxt); - if (xmlValidateDtd(xmlNewValidCtxt(), doc, dtd) != 1) - validationFailed = true; -#else - /* if dtd for our xml data is detected... */ - if ((doc->intSubset != NULL) || (doc->extSubset != NULL)) - { - /* assume inline DTD exists - validation should be performed */ - if (ctxt->valid == 0) - { - /* DTD exists, but validator reported 'validation failed' */ - validationFailed = true; - } - } -#endif - - if (validationFailed) - xml_ereport(WARNING, ERRCODE_INVALID_XML_DOCUMENT, - "validation against DTD failed", ctxt); - /* TODO encoding issues * (thoughts: * CASE: @@ -517,10 +486,6 @@ xml_parse(text *data, int opts, bool is_document) * ) */ /* ... */ -#ifdef XML_DEBUG_DTD_CONST - if (dtd) - xmlFreeDtd(dtd); -#endif if (doc) xmlFreeDoc(doc); if (ctxt) @@ -529,10 +494,6 @@ xml_parse(text *data, int opts, bool is_document) } PG_CATCH(); { -#ifdef XML_DEBUG_DTD_CONST - if (dtd) - xmlFreeDtd(dtd); -#endif if (doc) xmlFreeDoc(doc); if (ctxt) |