msxml3: Expose the XML parser SAX callback interface.

This eliminates a few function calls; libxml will call this indirectly
through the old method.  By writing our own callback functions or
wrapping the default ones we can manipulate the xmlDoc as it's being
parsed, allowing us to match the way msxml parses.
This commit is contained in:
Adam Martinson 2010-09-29 16:04:38 -05:00 committed by Alexandre Julliard
parent 042ecec8b6
commit 776a8662f0
1 changed files with 41 additions and 14 deletions

View File

@ -50,6 +50,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msxml);
#include <libxml/xpathInternals.h> #include <libxml/xpathInternals.h>
#include <libxml/xmlsave.h> #include <libxml/xmlsave.h>
#include <libxml/SAX2.h>
/* not defined in older versions */ /* not defined in older versions */
#define XML_SAVE_FORMAT 1 #define XML_SAVE_FORMAT 1
@ -287,21 +288,47 @@ xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc)
return node; return node;
} }
static xmlDocPtr doparse( char *ptr, int len, const char *encoding ) static xmlDocPtr doparse(domdoc* This, char *ptr, int len)
{ {
xmlDocPtr doc; xmlDocPtr doc;
static xmlSAXHandler sax_handler = {
xmlSAX2InternalSubset, /* internalSubset */
xmlSAX2IsStandalone, /* isStandalone */
xmlSAX2HasInternalSubset, /* hasInternalSubset */
xmlSAX2HasExternalSubset, /* hasExternalSubset */
xmlSAX2ResolveEntity, /* resolveEntity */
xmlSAX2GetEntity, /* getEntity */
xmlSAX2EntityDecl, /* entityDecl */
xmlSAX2NotationDecl, /* notationDecl */
xmlSAX2AttributeDecl, /* attributeDecl */
xmlSAX2ElementDecl, /* elementDecl */
xmlSAX2UnparsedEntityDecl, /* unparsedEntityDecl */
xmlSAX2SetDocumentLocator, /* setDocumentLocator */
xmlSAX2StartDocument, /* startDocument */
xmlSAX2EndDocument, /* endDocument */
xmlSAX2StartElement, /* startElement */
xmlSAX2EndElement, /* endElement */
xmlSAX2Reference, /* reference */
xmlSAX2Characters, /* characters */
NULL, /* TODO: ignorableWhitespace */
xmlSAX2ProcessingInstruction, /* processingInstruction */
xmlSAX2Comment, /* comment */
NULL, /* TODO: warning */
NULL, /* TODO: error */
NULL, /* TODO: fatalError */
xmlSAX2GetParameterEntity, /* getParameterEntity */
xmlSAX2CDataBlock, /* cdataBlock */
xmlSAX2ExternalSubset, /* externalSubset */
0, /* initialized */
NULL, /* _private */
xmlSAX2StartElementNs, /* startElementNs */
xmlSAX2EndElementNs, /* endElementNs */
NULL /* TODO: serror */
};
#ifdef HAVE_XMLREADMEMORY doc = xmlSAXParseMemoryWithData(&sax_handler, ptr, len, 0, This);
/*
* use xmlReadMemory if possible so we can suppress
* writing errors to stderr
*/
doc = xmlReadMemory( ptr, len, NULL, encoding,
XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOBLANKS );
#else
doc = xmlParseMemory( ptr, len );
#endif
/* TODO: put this in one of the SAX callbacks */
/* create first child as a <?xml...?> */ /* create first child as a <?xml...?> */
if (doc && doc->standalone != -1) if (doc && doc->standalone != -1)
{ {
@ -531,7 +558,7 @@ static HRESULT WINAPI domdoc_IPersistStreamInit_Load(
len = GlobalSize(hglobal); len = GlobalSize(hglobal);
ptr = GlobalLock(hglobal); ptr = GlobalLock(hglobal);
if (len != 0) if (len != 0)
xmldoc = doparse(ptr, len, NULL); xmldoc = doparse(This, ptr, len);
GlobalUnlock(hglobal); GlobalUnlock(hglobal);
if (!xmldoc) if (!xmldoc)
@ -1718,7 +1745,7 @@ static HRESULT domdoc_onDataAvailable(void *obj, char *ptr, DWORD len)
domdoc *This = obj; domdoc *This = obj;
xmlDocPtr xmldoc; xmlDocPtr xmldoc;
xmldoc = doparse( ptr, len, NULL ); xmldoc = doparse(This, ptr, len);
if(xmldoc) { if(xmldoc) {
xmldoc->_private = create_priv(); xmldoc->_private = create_priv();
return attach_xmldoc(This, xmldoc); return attach_xmldoc(This, xmldoc);
@ -1956,7 +1983,7 @@ static HRESULT WINAPI domdoc_loadXML(
if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) ) if ( bstrXML && bstr_to_utf8( bstrXML, &str, &len ) )
{ {
xmldoc = doparse( str, len, "UTF-8" ); xmldoc = doparse(This, str, len);
heap_free( str ); heap_free( str );
if ( !xmldoc ) if ( !xmldoc )
This->error = E_FAIL; This->error = E_FAIL;