Closed Bug 375983 Opened 17 years ago Closed 17 years ago

xsi:type not on root element is ignored

Categories

(Core Graveyard :: XForms, defect)

defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: sspeiche, Assigned: sspeiche)

Details

(Keywords: fixed1.8.0.12, fixed1.8.1.4)

Attachments

(3 files)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3
Build Identifier: 

When a referenced, or inline, xml instance has nodes with
redefined types using xsi:type, this information is ignored.
Validator only looks for it on ValidateNode(node) that is passed
in, which is typically the root document element only and then
walks the DOM with internal methods that track location along
associated schema.  Need to check for xsi:type on elements.
Note, this could be changed if and when DOM Level 3 Core's
Element.schemaTypeInfo

Reproducible: Always
Attached file test case
Attached patch patchSplinter Review
Attachment #260120 - Flags: review?(doronr)
Comment on attachment 260120 [details] [diff] [review]
patch

>? xsitype.diff
>Index: nsSchemaValidator.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/extensions/schema-validation/src/nsSchemaValidator.cpp,v
>retrieving revision 1.36
>diff -u -8 -p -r1.36 nsSchemaValidator.cpp
>--- nsSchemaValidator.cpp	27 Mar 2007 21:55:06 -0000	1.36
>+++ nsSchemaValidator.cpp	30 Mar 2007 01:38:58 -0000
>@@ -170,87 +170,23 @@ nsSchemaValidator::Validate(nsIDOMNode* 
>   LOG(("--------- nsSchemaValidator::Validate called ---------"));
> 
>   if (!aElement)
>     return NS_ERROR_SCHEMAVALIDATOR_NO_DOM_NODE_SPECIFIED;
> 
>   // init the override
>   mForceInvalid = PR_FALSE;
> 
>-  nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(aElement);
>-  NS_ENSURE_STATE(domElement);
>-
>-  PRBool hasTypeAttribute = PR_FALSE;
>-  nsresult rv = domElement->HasAttributeNS(NS_LITERAL_STRING(
>-                                             NS_SCHEMA_INSTANCE_NAMESPACE),
>-                                           NS_LITERAL_STRING("type"),
>-                                           &hasTypeAttribute);
>-  NS_ENSURE_SUCCESS(rv, rv);
>-
>   // will hold the type to validate against
>   nsCOMPtr<nsISchemaType> type;
> 
>-  if (hasTypeAttribute) {
>-    LOG(("  -- found type attribute"));
>-
>-    nsAutoString typeAttribute;
>-    rv = domElement->GetAttributeNS(NS_LITERAL_STRING(
>-                                      NS_SCHEMA_INSTANCE_NAMESPACE),
>-                                    NS_LITERAL_STRING("type"),
>-                                    typeAttribute);
>-    NS_ENSURE_SUCCESS(rv, rv);
>-    LOG(("  Type is: %s", NS_ConvertUTF16toUTF8(typeAttribute).get()));
>-
>-    if (typeAttribute.IsEmpty())
>-      return NS_ERROR_SCHEMAVALIDATOR_NO_TYPE_FOUND;
>-
>-    // split type (ns:type) into namespace and type.
>-    nsCOMPtr<nsIParserService> parserService =
>-      do_GetService("@mozilla.org/parser/parser-service;1", &rv);
>-    NS_ENSURE_SUCCESS(rv, rv);
>-
>-    const nsAFlatString& qName = PromiseFlatString(typeAttribute);
>-    const PRUnichar *colon;
>-    rv = parserService->CheckQName(qName, PR_TRUE, &colon);
>-    NS_ENSURE_SUCCESS(rv, rv);
>-
>-    const PRUnichar* end;
>-    qName.EndReading(end);
>-
>-    nsAutoString schemaTypePrefix, schemaType, schemaTypeNamespace;
>-    if (!colon) {
>-      // colon not found, so no prefix
>-      schemaType.Assign(typeAttribute);
>-
>-      // get namespace from node
>-      aElement->GetNamespaceURI(schemaTypeNamespace);
>-    } else {
>-      schemaTypePrefix.Assign(Substring(qName.get(), colon));
>-      schemaType.Assign(Substring(colon + 1, end));
>-
>-      // get the namespace url from the prefix
>-      nsCOMPtr<nsIDOM3Node> domNode3 = do_QueryInterface(aElement);
>-      rv = domNode3->LookupNamespaceURI(schemaTypePrefix, schemaTypeNamespace);
>-      NS_ENSURE_SUCCESS(rv, rv);
>-    }
>-
>-    LOG(("  Type to validate against is %s:%s",
>-      NS_LossyConvertUTF16toASCII(schemaTypePrefix).get(),
>-      NS_LossyConvertUTF16toASCII(schemaType).get()));
>-
>-    // no schemas loaded and type is not builtin, abort
>-    if (!mSchema &&
>-        !schemaTypeNamespace.EqualsLiteral(NS_SCHEMA_1999_NAMESPACE) &&
>-        !schemaTypeNamespace.EqualsLiteral(NS_SCHEMA_2001_NAMESPACE))
>-      return NS_ERROR_SCHEMAVALIDATOR_NO_SCHEMA_LOADED;
>+  nsresult rv = GetElementXsiType(aElement, getter_AddRefs(type));
>+  NS_ENSURE_SUCCESS(rv, rv);
> 
>-    // get the type
>-    rv = GetType(schemaType, schemaTypeNamespace, getter_AddRefs(type));
>-    NS_ENSURE_SUCCESS(rv, rv);
>-  } else if (mSchema) {
>+  if (!type && mSchema) {
>     // no type attribute, look for an xsd:element in the schema that matches
>     LOG(("   -- no type attribute found, so looking for matching xsd:element"));
> 
>     // get namespace from node
>     nsAutoString schemaTypeNamespace;
>     rv = aElement->GetNamespaceURI(schemaTypeNamespace);
>     NS_ENSURE_SUCCESS(rv, rv);
> 
>@@ -4281,30 +4217,119 @@ nsSchemaValidator::ValidateComplexPartic
> 
>   leftOvers.swap(*aLeftOvers);
>   *aNotFound = notFound;
>   *aResult = isValid;
>   return rv;
> }
> 
> nsresult
>+nsSchemaValidator::GetElementXsiType(nsIDOMNode*     aNode,
>+                                  nsISchemaType** aType)
>+{
>+
>+  nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(aNode);
>+  NS_ENSURE_STATE(domElement);
>+
>+  PRBool hasTypeAttribute = PR_FALSE;
>+  nsresult rv = domElement->HasAttributeNS(NS_LITERAL_STRING(
>+                                             NS_SCHEMA_INSTANCE_NAMESPACE),
>+                                           NS_LITERAL_STRING("type"),
>+                                           &hasTypeAttribute);
>+  NS_ENSURE_SUCCESS(rv, rv);
>+
>+  /* XXX: This all may need to change when 
>+     element.GetSchemaTypeInfo() is implemented from DOM Level 3 Core,
>+     see:
>+     http://www.w3.org/TR/DOM-Level-3-Core/core.html#Attr-schemaTypeInfo
>+  */
>+
>+  if (hasTypeAttribute) {
>+    LOG(("  -- found xsi:type attribute"));
>+
>+    nsAutoString typeAttribute;
>+    rv = domElement->GetAttributeNS(NS_LITERAL_STRING(
>+                                      NS_SCHEMA_INSTANCE_NAMESPACE),
>+                                    NS_LITERAL_STRING("type"),
>+                                    typeAttribute);
>+    NS_ENSURE_SUCCESS(rv, rv);
>+    LOG(("  Type is: %s", NS_ConvertUTF16toUTF8(typeAttribute).get()));
>+
>+    if (typeAttribute.IsEmpty())
>+      return NS_ERROR_SCHEMAVALIDATOR_NO_TYPE_FOUND;
>+
>+    // split type (ns:type) into namespace and type.
>+    nsCOMPtr<nsIParserService> parserService =
>+      do_GetService("@mozilla.org/parser/parser-service;1", &rv);
>+    NS_ENSURE_SUCCESS(rv, rv);
>+
>+    const nsAFlatString& qName = PromiseFlatString(typeAttribute);
>+    const PRUnichar *colon;
>+    rv = parserService->CheckQName(qName, PR_TRUE, &colon);
>+    NS_ENSURE_SUCCESS(rv, rv);
>+
>+    const PRUnichar* end;
>+    qName.EndReading(end);
>+
>+    nsAutoString schemaTypePrefix, schemaType, schemaTypeNamespace;
>+    if (!colon) {
>+      // colon not found, so no prefix
>+      schemaType.Assign(typeAttribute);
>+
>+      // get namespace from node
>+      aNode->GetNamespaceURI(schemaTypeNamespace);
>+    } else {
>+      schemaTypePrefix.Assign(Substring(qName.get(), colon));
>+      schemaType.Assign(Substring(colon + 1, end));
>+
>+      // get the namespace url from the prefix
>+      nsCOMPtr<nsIDOM3Node> domNode3 = do_QueryInterface(aNode);
>+      rv = domNode3->LookupNamespaceURI(schemaTypePrefix, schemaTypeNamespace);
>+      NS_ENSURE_SUCCESS(rv, rv);
>+    }
>+
>+    LOG(("  Type to validate against is %s:%s",
>+      NS_LossyConvertUTF16toASCII(schemaTypePrefix).get(),
>+      NS_LossyConvertUTF16toASCII(schemaType).get()));
>+
>+    // no schemas loaded and type is not builtin, abort
>+    if (!mSchema &&
>+        !schemaTypeNamespace.EqualsLiteral(NS_SCHEMA_1999_NAMESPACE) &&
>+        !schemaTypeNamespace.EqualsLiteral(NS_SCHEMA_2001_NAMESPACE))
>+      return NS_ERROR_SCHEMAVALIDATOR_NO_SCHEMA_LOADED;
>+
>+    // get the type
>+    rv = GetType(schemaType, schemaTypeNamespace, aType);
>+    NS_ENSURE_SUCCESS(rv, rv);
>+  }
>+
>+  return rv;
>+}
>+
>+nsresult
> nsSchemaValidator::ValidateComplexElement(nsIDOMNode* aNode,
>                                           nsISchemaParticle *aSchemaParticle,
>                                           PRBool *aResult)
> {
>   PRBool isValid = PR_FALSE;
> 
>   nsCOMPtr<nsISchemaElement> schemaElement(do_QueryInterface(aSchemaParticle));
> 
>   if (!schemaElement)
>     return NS_ERROR_UNEXPECTED;
> 
>+  // will hold the type to validate against
>   nsCOMPtr<nsISchemaType> type;
>-  nsresult rv = schemaElement->GetType(getter_AddRefs(type));
>-  NS_ENSURE_SUCCESS(rv, rv);
>+
>+  nsresult rv = GetElementXsiType(aNode, getter_AddRefs(type));
>+
>+  if (!type) {
>+    rv = schemaElement->GetType(getter_AddRefs(type));
>+    NS_ENSURE_SUCCESS(rv, rv);
>+  }
> 
>   if (!type)
>     return NS_ERROR_UNEXPECTED;
> 
>   PRUint16 typeValue;
>   rv = type->GetSchemaType(&typeValue);
>   NS_ENSURE_SUCCESS(rv, rv);
> 
>Index: nsSchemaValidator.h
>===================================================================
>RCS file: /cvsroot/mozilla/extensions/schema-validation/src/nsSchemaValidator.h,v
>retrieving revision 1.12
>diff -u -8 -p -r1.12 nsSchemaValidator.h
>--- nsSchemaValidator.h	13 Mar 2007 05:28:21 -0000	1.12
>+++ nsSchemaValidator.h	30 Mar 2007 01:38:59 -0000
>@@ -345,16 +345,17 @@ private:
>   nsresult ValidateSchemaAttribute(nsIDOMNode* aNode, nsISchemaAttribute *aAttr,
>                                    const nsAString & aAttrName,
>                                    PRUint32 *aFoundAttrCount, PRBool *aResult);
>   nsresult ValidateSchemaAttributeGroup(nsIDOMNode* aNode,
>                                         nsISchemaAttributeGroup *aAttr,
>                                         const nsAString & aAttrName,
>                                         PRUint32 *aFoundAttrCount,
>                                         PRBool *aResult);
>+  nsresult GetElementXsiType(nsIDOMNode* aNode, nsISchemaType** aType);
> 
> static void
> ReleaseObject(void    *aObject,
>               nsIAtom *aPropertyName,
>               void    *aPropertyValue,
>               void    *aData)
> {
>   NS_STATIC_CAST(nsISupports *, aPropertyValue)->Release();
Attachment #260120 - Flags: review?(doronr) → review+
Attachment #260120 - Flags: review?(aaronr)
Assignee: xforms → sspeiche
Status: UNCONFIRMED → NEW
Ever confirmed: true
Comment on attachment 260120 [details] [diff] [review]
patch

>Index: nsSchemaValidator.cpp
>===================================================================

> nsresult
>+nsSchemaValidator::GetElementXsiType(nsIDOMNode*     aNode,
>+                                  nsISchemaType** aType)
>+{
>+

nit: I know the style rules in schema-validator are more lax, but at least make the parameter types line up :-)


> nsSchemaValidator::ValidateComplexElement(nsIDOMNode* aNode,
>                                           nsISchemaParticle *aSchemaParticle,
>                                           PRBool *aResult)
> {
>   PRBool isValid = PR_FALSE;
> 
>   nsCOMPtr<nsISchemaElement> schemaElement(do_QueryInterface(aSchemaParticle));
> 
>   if (!schemaElement)
>     return NS_ERROR_UNEXPECTED;
> 
>+  // will hold the type to validate against
>   nsCOMPtr<nsISchemaType> type;
>-  nsresult rv = schemaElement->GetType(getter_AddRefs(type));
>-  NS_ENSURE_SUCCESS(rv, rv);
>+
>+  nsresult rv = GetElementXsiType(aNode, getter_AddRefs(type));
>+

nit: shouldn't you NS_ENSURE_SUCCESS(rv, rv) here?

>+  if (!type) {
>+    rv = schemaElement->GetType(getter_AddRefs(type));
>+    NS_ENSURE_SUCCESS(rv, rv);
>+  }
> 
>   if (!type)
>     return NS_ERROR_UNEXPECTED;

nit: shouldn't you move this up into the if (!type) test?  Otherwise you are running the same test twice if xsi:type is set, when you don't really need to.

with those, r=me
Attachment #260120 - Flags: review?(aaronr) → review+
checked in for sspeiche
Status: NEW → RESOLVED
Closed: 17 years ago
Resolution: --- → FIXED
Whiteboard: xf-to-branch
checked into 1.8 branch on 2007-04-12
checked into 1.8.0 branch on 2007-04-16
Whiteboard: xf-to-branch
Product: Core → Core Graveyard
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: