зеркало из https://github.com/mozilla/pjs.git
XForms bug 329136 - XForms needs to validate instance documents against their schema. r=aaronr, allan
This commit is contained in:
Родитель
c4ba2c6a58
Коммит
7f5951abc8
|
@ -1518,6 +1518,62 @@ nsXFormsModelElement::ValidateNode(nsIDOMNode *aInstanceNode, PRBool *aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsModelElement::ValidateDocument(nsIDOMDocument *aInstanceDocument,
|
||||
PRBool *aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
NS_ENSURE_ARG(aInstanceDocument);
|
||||
|
||||
/*
|
||||
This will process the instance document and check for schema validity. It
|
||||
will mark nodes in the document with their schema types using nsIProperty
|
||||
until it hits a structural schema validation error. So if the instance
|
||||
document's XML structure is invalid, don't expect type properties to be
|
||||
set.
|
||||
|
||||
Note that if the structure is fine but some simple types nodes (nodes
|
||||
that contain text only) are invalid (say one has a empty nodeValue but
|
||||
should be a date), the schema validator will continue processing and add
|
||||
the type properties. Schema validation will return false at the end.
|
||||
*/
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
nsresult rv = aInstanceDocument->GetDocumentElement(getter_AddRefs(element));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool isValid = PR_FALSE;
|
||||
|
||||
// get namespace from node
|
||||
nsAutoString nsuri;
|
||||
element->GetNamespaceURI(nsuri);
|
||||
|
||||
nsCOMPtr<nsISchemaCollection> schemaColl = do_QueryInterface(mSchemas);
|
||||
NS_ENSURE_STATE(schemaColl);
|
||||
|
||||
nsCOMPtr<nsISchema> schema;
|
||||
schemaColl->GetSchema(nsuri, getter_AddRefs(schema));
|
||||
if (schema) {
|
||||
nsXFormsSchemaValidator validator;
|
||||
validator.LoadSchema(schema);
|
||||
// Validate will validate the node and its subtree, as per the schema
|
||||
// specification.
|
||||
isValid = validator.Validate(element);
|
||||
} else {
|
||||
// no schema found for the instance document's namespace.
|
||||
nsCOMPtr<nsIDOMNode> instanceElement;
|
||||
nsXFormsUtils::GetInstanceNodeForData(element,
|
||||
getter_AddRefs(instanceElement));
|
||||
const PRUnichar *strings[] = { nsuri.get() };
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("noSchemaForInstance"),
|
||||
strings, 1, instanceElement, nsnull);
|
||||
rv = NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
*aResult = isValid;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* SUBMIT_SERIALIZE_NODE - node is to be serialized
|
||||
* SUBMIT_SKIP_NODE - node is not to be serialized
|
||||
|
@ -1588,6 +1644,21 @@ nsXFormsModelElement::GetTypeFromNode(nsIDOMNode *aInstanceData,
|
|||
// If there was no type information on the node itself, check for a type
|
||||
// bound to the node via \<xforms:bind\>
|
||||
if (!typeVal && !mNodeToType.Get(aInstanceData, &typeVal)) {
|
||||
// check if schema validation left us a nsISchemaType*
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aInstanceData);
|
||||
|
||||
if (content) {
|
||||
nsISchemaType *type;
|
||||
nsCOMPtr<nsIAtom> myAtom = do_GetAtom("xsdtype");
|
||||
|
||||
type = NS_STATIC_CAST(nsISchemaType *, content->GetProperty(myAtom));
|
||||
if (type) {
|
||||
type->GetName(aType);
|
||||
type->GetTargetNamespace(aNSUri);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// No type information found
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
@ -1932,6 +2003,37 @@ nsXFormsModelElement::MaybeNotifyCompletion()
|
|||
nsXFormsUtils::DispatchEvent(model->mElement, eEvent_ModelConstructDone);
|
||||
}
|
||||
|
||||
// validate the instance documents becauar we want schemaValidation to add
|
||||
// schema type properties from the schema file unto our instance document
|
||||
// elements. We don't care about the validation results.
|
||||
if (mInstanceDocuments) {
|
||||
PRUint32 instCount;
|
||||
mInstanceDocuments->GetLength(&instCount);
|
||||
if (instCount) {
|
||||
nsCOMPtr<nsIDOMDocument> document;
|
||||
|
||||
for (PRUint32 i = 0; i < instCount; ++i) {
|
||||
nsIInstanceElementPrivate* instEle = mInstanceDocuments->GetInstanceAt(i);
|
||||
nsCOMPtr<nsIXFormsNSInstanceElement> NSInstEle(instEle);
|
||||
NSInstEle->GetInstanceDocument(getter_AddRefs(document));
|
||||
NS_ASSERTION(document, "nsIXFormsNSInstanceElement::GetInstanceDocument returned null?!");
|
||||
|
||||
if (document) {
|
||||
PRBool isValid = PR_FALSE;
|
||||
ValidateDocument(document, &isValid);
|
||||
|
||||
if (!isValid) {
|
||||
nsCOMPtr<nsIDOMElement> instanceElement;
|
||||
instEle->GetElement(getter_AddRefs(instanceElement));
|
||||
|
||||
nsXFormsUtils::ReportError(NS_LITERAL_STRING("instDocumentInvalid"),
|
||||
instanceElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsXFormsModelElement::ProcessDeferredBinds(domDoc);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
||||
|
|
|
@ -351,6 +351,9 @@ private:
|
|||
NS_HIDDEN_(nsresult) RefreshSubTree(nsXFormsControlListItem *aCurrent,
|
||||
PRBool aForceRebind);
|
||||
|
||||
NS_HIDDEN_(nsresult) ValidateDocument(nsIDOMDocument *aInstanceDocument,
|
||||
PRBool *aResult);
|
||||
|
||||
nsIDOMElement *mElement;
|
||||
nsCOMPtr<nsISchemaLoader> mSchemas;
|
||||
nsStringArray mPendingInlineSchemas;
|
||||
|
|
|
@ -83,28 +83,12 @@ nsXFormsSchemaValidator::ValidateString(const nsAString & aValue,
|
|||
}
|
||||
|
||||
PRBool
|
||||
nsXFormsSchemaValidator::ValidateNode(nsIDOMNode* aElement,
|
||||
const nsAString & aType,
|
||||
const nsAString & aNamespace)
|
||||
nsXFormsSchemaValidator::Validate(nsIDOMNode* aElement)
|
||||
{
|
||||
PRBool isValid = PR_FALSE;
|
||||
NS_ENSURE_TRUE(mSchemaValidator, isValid);
|
||||
|
||||
if (aNamespace.EqualsLiteral(NS_NAMESPACE_XFORMS)) {
|
||||
// XXX: currently, we will only support validating a lone node. When
|
||||
// we get complex type support, we should load the schema for the xforms
|
||||
// types and use ValidateAgainstType like below.
|
||||
nsAutoString nodeValue;
|
||||
nsCOMPtr<nsIDOM3Node> domNode3 = do_QueryInterface(aElement);
|
||||
domNode3->GetTextContent(nodeValue);
|
||||
|
||||
isValid = ValidateString(nodeValue, aType, aNamespace);
|
||||
} else {
|
||||
nsCOMPtr<nsISchemaType> type;
|
||||
if (GetType(aType, aNamespace, getter_AddRefs(type))) {
|
||||
mSchemaValidator->ValidateAgainstType(aElement, type, &isValid);
|
||||
}
|
||||
}
|
||||
mSchemaValidator->Validate(aElement, &isValid);
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
|
|
@ -64,15 +64,12 @@ public:
|
|||
const nsAString & aNamespace);
|
||||
|
||||
/**
|
||||
* Validates a node against a namespace and schema type
|
||||
* Validates a node and its subtree against the loaded schema(s)
|
||||
*
|
||||
* @param aElement Node to validate
|
||||
* @param aType Type
|
||||
* @param aNamespace Namespace
|
||||
* @return Whether the string is valid or not
|
||||
*/
|
||||
PRBool ValidateNode(nsIDOMNode* aElement, const nsAString & aType,
|
||||
const nsAString & aNamespace);
|
||||
PRBool Validate(nsIDOMNode* aElement);
|
||||
|
||||
/**
|
||||
* Returns a nsISchemaType given an type and namespace
|
||||
|
|
|
@ -71,10 +71,12 @@ externalLinkLoadOrigin = XForms Error (32): Security check failed! Trying to loa
|
|||
instanceNotFound = XForms Error (33): Could not find instance with id == '%S'
|
||||
defInstanceNotFound = XForms Error (34): Could not find default instance
|
||||
MDGLoopError = XForms Error (35): There are loops in the bindings of the model!
|
||||
noSchemaForInstance = XForms Error (36): Could not find a schema for validating the instance document (namespace=%S)
|
||||
|
||||
# Warning Messages:
|
||||
warnSOAP = XForms Warning (1): You are using the SOAP post feature, which is an experimental feature! Beware that the functionality might change, and forms may stop working at any time.
|
||||
warnMailtoBodyParam = XForms Warning (2): The submission action uri already contains a body parameter.
|
||||
instDocumentInvalid = XForms Warning (3): Instance document did not validate.
|
||||
|
||||
# XForms Permission Messages:
|
||||
xformsXDPermissionDialogTitle = Allowed Sites - XForms Cross Domain Access
|
||||
|
|
Загрузка…
Ссылка в новой задаче