/// <summary> /// Only validation whether the children elements are valid according to this type's constraint defined in schema. /// </summary> /// <param name="validationContext">The validation context.</param> internal void Validate(ValidationContext validationContext) { Debug.Assert(validationContext != null); Debug.Assert(validationContext.Element != null); OpenXmlElement theElement = validationContext.Element; Debug.Assert(!(theElement is OpenXmlUnknownElement)); Debug.Assert(!(theElement is OpenXmlMiscNode)); if (theElement.ElementTypeId < ReservedElementTypeIds.MaxReservedId) { // MiscElement, UnknownElement, // AlternateContent, AlternateContentChoice, AlternateContentFallback if (theElement.ElementTypeId == ReservedElementTypeIds.AlternateContentId) { AlternateContentValidator.Validate(validationContext); } Debug.Assert(!(theElement is AlternateContentChoice)); Debug.Assert(!(theElement is AlternateContentFallback)); return; } // validte Inorable, ProcessContent, etc. compatibility-rule attributes CompatibilityRuleAttributesValidator.ValidateMcAttributes(validationContext); SchemaTypeData schemaTypeData = this._sdbSchemaDatas.GetSchemaTypeData(theElement); ValidateAttributes(validationContext, schemaTypeData); // validate particles if (theElement is OpenXmlLeafTextElement) { SimpleContentComplexTypeValidator.Validate(validationContext, schemaTypeData.SimpleTypeConstraint); } else if (theElement is OpenXmlLeafElement) { EmptyComplexTypeValidator.Validate(validationContext); } else { Debug.Assert(theElement is OpenXmlCompositeElement); Debug.Assert(!(theElement is AlternateContentChoice)); Debug.Assert(!(theElement is AlternateContentFallback)); if (schemaTypeData.ParticleConstraint != null) { // composite element CompositeComplexTypeValidator.Validate(validationContext, schemaTypeData.ParticleConstraint); } else { // special case, see O14 bug #662644 // A root element which does not allow any children. Debug.Assert(theElement is OpenXmlPartRootElement); EmptyRootComplexTypeValidator.Validate(validationContext); } } }
/// <summary> /// Validate the attributes constraint. /// </summary> /// <param name="validationContext">The validation context.</param> /// <param name="schemaTypeData">The constraint data of the schema type.</param> private static void ValidateAttributes(ValidationContext validationContext, SchemaTypeData schemaTypeData) { var element = validationContext.Element; Debug.Assert( element.Attributes == null && schemaTypeData.AttributeConstraintsCount == 0 || element.Attributes.Length == schemaTypeData.AttributeConstraintsCount ); ValidationErrorInfo errorInfo; // validate xsd:use on attributes for (int i = 0; i < schemaTypeData.AttributeConstraintsCount; i++) { var attributeConstraint = schemaTypeData.AttributeConstraints[i]; if (attributeConstraint.SupportedVersion.Includes(validationContext.FileFormat)) { // only check the attribute constraints defined in the specified file format version. switch (attributeConstraint.XsdAttributeUse) { case XsdAttributeUse.Required: if (element.Attributes[i] == null) { string attributeQname = element.GetFixedAttributeQname(i).ToString(); // error: miss required attribute errorInfo = validationContext.ComposeSchemaValidationError(element, null, "Sch_MissRequiredAttribute", attributeQname); errorInfo.SetDebugField(attributeQname, "Sch_MissRequiredAttribute"); validationContext.EmitError(errorInfo); } break; case XsdAttributeUse.None: // none, so use default "optional" case XsdAttributeUse.Optional: break; case XsdAttributeUse.Prohibited: // no "prohibited" in Ecma at now. default: Debug.Assert(false); break; } if (element.Attributes[i] != null) { OpenXmlSimpleType attributeValue = element.Attributes[i]; string attributeQname = element.GetFixedAttributeQname(i).ToString(); ValidateValue(validationContext, attributeConstraint.SimpleTypeConstraint, attributeValue, attributeQname, true); } } else { if (element.Attributes[i] != null) { // The attribute is not defined in the specified version, report error. if (validationContext.McContext.IsIgnorableNs(element.AttributeNamespaceIds[i])) { // Ignorable attribute, no error. } else { // emit error string attributeQname = element.GetFixedAttributeQname(i).ToString(); ; errorInfo = validationContext.ComposeSchemaValidationError(element, null, "Sch_UndeclaredAttribute", attributeQname); errorInfo.SetDebugField(attributeQname, "Sch_UndeclaredAttribute"); validationContext.EmitError(errorInfo); } } } } // all unknown attributes (attributes not defined in schema) are in ExtendedAttributes. // they should be errors foreach (var extendedAttribute in element.ExtendedAttributes) { if (validationContext.McContext.IsIgnorableNs(extendedAttribute.NamespaceUri)) { // Ignorable attribute, no error. } // xml:space is always allowed else if ("http://www.w3.org/XML/1998/namespace" == extendedAttribute.NamespaceUri) { } else { // emit error string attributeQname = extendedAttribute.XmlQualifiedName.ToString(); errorInfo = validationContext.ComposeSchemaValidationError(element, null, "Sch_UndeclaredAttribute", attributeQname); errorInfo.SetDebugField(attributeQname, "Sch_UndeclaredAttribute"); validationContext.EmitError(errorInfo); } } }
/// <summary> /// Validate the attributes constraint. /// </summary> /// <param name="validationContext">The validation context.</param> /// <param name="schemaTypeData">The constraint data of the schema type.</param> private static void ValidateAttributes(ValidationContext validationContext, SchemaTypeData schemaTypeData) { var element = validationContext.Element; Debug.Assert(element.Attributes == null && schemaTypeData.AttributeConstraintsCount == 0 || element.Attributes.Length == schemaTypeData.AttributeConstraintsCount); ValidationErrorInfo errorInfo; // validate xsd:use on attributes for (int i = 0; i < schemaTypeData.AttributeConstraintsCount; i++) { var attributeConstraint = schemaTypeData.AttributeConstraints[i]; if (attributeConstraint.SupportedVersion.Includes(validationContext.FileFormat)) { // only check the attribute constraints defined in the specified file format version. switch (attributeConstraint.XsdAttributeUse) { case XsdAttributeUse.Required: if (element.Attributes[i] == null) { string attributeQname = element.GetFixedAttributeQname(i).ToString(); // error: miss required attribute errorInfo = validationContext.ComposeSchemaValidationError(element, null, "Sch_MissRequiredAttribute", attributeQname); errorInfo.SetDebugField(attributeQname, "Sch_MissRequiredAttribute"); validationContext.EmitError(errorInfo); } break; case XsdAttributeUse.None: // none, so use default "optional" case XsdAttributeUse.Optional: break; case XsdAttributeUse.Prohibited: // no "prohibited" in Ecma at now. default: Debug.Assert(false); break; } if (element.Attributes[i] != null) { OpenXmlSimpleType attributeValue = element.Attributes[i]; string attributeQname = element.GetFixedAttributeQname(i).ToString(); ValidateValue(validationContext, attributeConstraint.SimpleTypeConstraint, attributeValue, attributeQname, true); } } else { if (element.Attributes[i] != null) { // The attribute is not defined in the specified version, report error. if (validationContext.McContext.IsIgnorableNs(element.AttributeNamespaceIds[i])) { // Ignorable attribute, no error. } else { // emit error string attributeQname = element.GetFixedAttributeQname(i).ToString();; errorInfo = validationContext.ComposeSchemaValidationError(element, null, "Sch_UndeclaredAttribute", attributeQname); errorInfo.SetDebugField(attributeQname, "Sch_UndeclaredAttribute"); validationContext.EmitError(errorInfo); } } } } // all unknown attributes (attributes not defined in schema) are in ExtendedAttributes. // they should be errors foreach (var extendedAttribute in element.ExtendedAttributes) { if (validationContext.McContext.IsIgnorableNs(extendedAttribute.NamespaceUri)) { // Ignorable attribute, no error. } // xml:space is always allowed else if ("http://www.w3.org/XML/1998/namespace" == extendedAttribute.NamespaceUri) { } else { // emit error string attributeQname = extendedAttribute.XmlQualifiedName.ToString(); errorInfo = validationContext.ComposeSchemaValidationError(element, null, "Sch_UndeclaredAttribute", attributeQname); errorInfo.SetDebugField(attributeQname, "Sch_UndeclaredAttribute"); validationContext.EmitError(errorInfo); } } }