From bf11a93b05142e005f3e9e0909823c0d80cdcea1 Mon Sep 17 00:00:00 2001 From: Adam Martinson Date: Mon, 1 Nov 2010 14:11:46 -0500 Subject: [PATCH] msxml3: Add a function to validate a tree against a schema cache. --- dlls/msxml3/msxml_private.h | 1 + dlls/msxml3/schema.c | 79 +++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index 3d7903cd68f..9dd02cbbfb8 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -197,6 +197,7 @@ extern HRESULT node_get_prefix(xmlnode*,BSTR*); extern HRESULT node_get_base_name(xmlnode*,BSTR*); extern HRESULT DOMDocument_create_from_xmldoc(xmlDocPtr xmldoc, IXMLDOMDocument3 **document); +extern HRESULT SchemaCache_validate_tree(IXMLDOMSchemaCollection2* iface, xmlNodePtr tree); static inline BSTR bstr_from_xmlChar(const xmlChar *str) { diff --git a/dlls/msxml3/schema.c b/dlls/msxml3/schema.c index 0120333d30e..1ff456626bb 100644 --- a/dlls/msxml3/schema.c +++ b/dlls/msxml3/schema.c @@ -611,6 +611,85 @@ static const struct IXMLDOMSchemaCollection2Vtbl schema_cache_vtbl = schema_cache_getDeclaration }; +static void LIBXML2_LOG_CALLBACK validate_error(void* ctx, char const* msg, ...) +{ + va_list ap; + va_start(ap, msg); + LIBXML2_CALLBACK_ERR(SchemaCache_validate_tree, msg, ap); + va_end(ap); +} + +static void LIBXML2_LOG_CALLBACK validate_warning(void* ctx, char const* msg, ...) +{ + va_list ap; + va_start(ap, msg); + LIBXML2_CALLBACK_WARN(SchemaCache_validate_tree, msg, ap); + va_end(ap); +} + +#ifdef HAVE_XMLSCHEMASSETVALIDSTRUCTUREDERRORS +static void validate_serror(void* ctx, xmlErrorPtr err) +{ + LIBXML2_CALLBACK_SERROR(SchemaCache_validate_tree, err); +} +#endif + +HRESULT SchemaCache_validate_tree(IXMLDOMSchemaCollection2* iface, xmlNodePtr tree) +{ + schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); + cache_entry* entry; + xmlChar const* ns = NULL; + TRACE("(%p, %p)\n", This, tree); + + if (!tree) + return E_POINTER; + + if ((xmlNodePtr)tree->doc == tree) + { + xmlNodePtr root = xmlDocGetRootElement(tree->doc); + if (root && root->ns) + ns = root->ns->href; + } + else if (tree->ns) + { + ns = tree->ns->href; + } + + entry = xmlHashLookup(This->cache, ns); + /* TODO: if the ns is not in the cache, and it's a URL, + * do we try to load from that? */ + if (entry) + { + if (entry->type == SCHEMA_TYPE_XDR) + { + FIXME("partial stub: XDR schema support not implemented\n"); + return S_OK; + } + else if (entry->type == SCHEMA_TYPE_XSD) + { + xmlSchemaValidCtxtPtr svctx; + int err; + /* TODO: if validateOnLoad property is false, + * we probably need to validate the schema here. */ + svctx = xmlSchemaNewValidCtxt(entry->schema); + xmlSchemaSetValidErrors(svctx, validate_error, validate_warning, NULL); +#ifdef HAVE_XMLSCHEMASSETVALIDSTRUCTUREDERRORS + xmlSchemaSetValidStructuredErrors(svctx, validate_serror, NULL); +#endif + + if ((xmlNodePtr)tree->doc == tree) + err = xmlSchemaValidateDoc(svctx, (xmlDocPtr)tree); + else + err = xmlSchemaValidateOneElement(svctx, tree); + + xmlSchemaFreeValidCtxt(svctx); + return err? S_FALSE : S_OK; + } + } + + return E_FAIL; +} + HRESULT SchemaCache_create(IUnknown* pUnkOuter, void** ppObj) { schema_cache* This = heap_alloc(sizeof(schema_cache));