From a1d69fcba798d5d3bbcf0870d3aceff583b6b995 Mon Sep 17 00:00:00 2001 From: Adam Martinson Date: Mon, 15 Nov 2010 18:16:51 -0600 Subject: [PATCH] msxml3: Add functions to get the dt:dt of a node. --- dlls/msxml3/msxml_private.h | 1 + dlls/msxml3/schema.c | 102 ++++++++++++++++++++++++++++++------ 2 files changed, 87 insertions(+), 16 deletions(-) diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h index 15c8b949502..9980fddf9b2 100644 --- a/dlls/msxml3/msxml_private.h +++ b/dlls/msxml3/msxml_private.h @@ -266,6 +266,7 @@ 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); +extern XDR_DT SchemaCache_get_node_dt(IXMLDOMSchemaCollection2* iface, xmlNodePtr node); extern XDR_DT dt_get_type(xmlChar const* str, int len /* calculated if -1 */); extern xmlChar const* dt_get_str(XDR_DT dt); diff --git a/dlls/msxml3/schema.c b/dlls/msxml3/schema.c index b93129577dc..ec31719776e 100644 --- a/dlls/msxml3/schema.c +++ b/dlls/msxml3/schema.c @@ -341,6 +341,23 @@ xmlChar const* dt_get_str(XDR_DT dt) return DT_string_table[dt]; } +static inline xmlChar const* get_node_nsURI(xmlNodePtr node) +{ + return (node->ns != NULL)? node->ns->href : NULL; +} + +static inline cache_entry* get_entry(schema_cache* This, xmlChar const* nsURI) +{ + return (!nsURI)? xmlHashLookup(This->cache, BAD_CAST "") : + xmlHashLookup(This->cache, nsURI); +} + +static inline xmlSchemaPtr get_node_schema(schema_cache* This, xmlNodePtr node) +{ + cache_entry* entry = get_entry(This, get_node_nsURI(node)); + return (!entry)? NULL : entry->schema; +} + xmlExternalEntityLoader _external_entity_loader = NULL; static xmlParserInputPtr external_entity_loader(const char *URL, const char *ID, @@ -981,6 +998,40 @@ static const struct IXMLDOMSchemaCollection2Vtbl schema_cache_vtbl = schema_cache_getDeclaration }; +static xmlSchemaElementPtr lookup_schema_elemDecl(xmlSchemaPtr schema, xmlNodePtr node) +{ + xmlSchemaElementPtr decl = NULL; + xmlChar const* nsURI = get_node_nsURI(node); + + TRACE("(%p, %p)\n", schema, node); + + if (xmlStrEqual(nsURI, schema->targetNamespace)) + decl = xmlHashLookup(schema->elemDecl, node->name); + + if (!decl && xmlHashSize(schema->schemasImports) > 1) + { + FIXME("declaration not found in main schema - need to check schema imports!\n"); + /*xmlSchemaImportPtr import; + if (nsURI == NULL) + import = xmlHashLookup(schema->schemasImports, XML_SCHEMAS_NO_NAMESPACE); + else + import = xmlHashLookup(schema->schemasImports, node->ns->href); + + if (import != NULL) + decl = xmlHashLookup(import->schema->elemDecl, node->name);*/ + } + + return decl; +} + +static inline xmlNodePtr lookup_schema_element(xmlSchemaPtr schema, xmlNodePtr node) +{ + xmlSchemaElementPtr decl = lookup_schema_elemDecl(schema, node); + while (decl != NULL && decl->refDecl != NULL) + decl = decl->refDecl; + return (decl != NULL)? decl->node : NULL; +} + static void LIBXML2_LOG_CALLBACK validate_error(void* ctx, char const* msg, ...) { va_list ap; @@ -1007,35 +1058,26 @@ static void validate_serror(void* ctx, xmlErrorPtr err) HRESULT SchemaCache_validate_tree(IXMLDOMSchemaCollection2* iface, xmlNodePtr tree) { schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); - cache_entry* entry; - xmlChar const* ns = NULL; + xmlSchemaPtr schema; + 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; - } + if (tree->type == XML_DOCUMENT_NODE) + tree = xmlDocGetRootElement(tree->doc); - entry = (ns != NULL)? xmlHashLookup(This->cache, ns) : - xmlHashLookup(This->cache, BAD_CAST ""); + schema = get_node_schema(This, tree); /* TODO: if the ns is not in the cache, and it's a URL, * do we try to load from that? */ - if (entry) + if (schema) { xmlSchemaValidCtxtPtr svctx; int err; /* TODO: if validateOnLoad property is false, * we probably need to validate the schema here. */ - svctx = xmlSchemaNewValidCtxt(entry->schema); + svctx = xmlSchemaNewValidCtxt(schema); xmlSchemaSetValidErrors(svctx, validate_error, validate_warning, NULL); #ifdef HAVE_XMLSCHEMASSETVALIDSTRUCTUREDERRORS xmlSchemaSetValidStructuredErrors(svctx, validate_serror, NULL); @@ -1053,6 +1095,34 @@ HRESULT SchemaCache_validate_tree(IXMLDOMSchemaCollection2* iface, xmlNodePtr tr return E_FAIL; } +XDR_DT SchemaCache_get_node_dt(IXMLDOMSchemaCollection2* iface, xmlNodePtr node) +{ + schema_cache* This = impl_from_IXMLDOMSchemaCollection2(iface); + xmlSchemaPtr schema = get_node_schema(This, node); + XDR_DT dt = DT_INVALID; + + TRACE("(%p, %p)\n", This, node); + + if (node->ns && xmlStrEqual(node->ns->href, DT_nsURI)) + { + dt = dt_get_type(node->name, -1); + } + else if (schema) + { + xmlChar* str; + xmlNodePtr schema_node = lookup_schema_element(schema, node); + + str = xmlGetNsProp(schema_node, BAD_CAST "dt", DT_nsURI); + if (str) + { + dt = dt_get_type(str, -1); + xmlFree(str); + } + } + + return dt; +} + HRESULT SchemaCache_create(IUnknown* pUnkOuter, void** ppObj) { schema_cache* This = heap_alloc(sizeof(schema_cache));