/// <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> public static 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.IsReservedElement()) { // MiscElement, UnknownElement, // AlternateContent, AlternateContentChoice, AlternateContentFallback if (theElement.IsAlternateContent()) { AlternateContentValidator.Validate(validationContext); } Debug.Assert(!(theElement is AlternateContentChoice)); Debug.Assert(!(theElement is AlternateContentFallback)); return; } // validate Ignorable, ProcessContent, etc. compatibility-rule attributes CompatibilityRuleAttributesValidator.ValidateMcAttributes(validationContext); ValidateAttributes(validationContext); // validate particles if (theElement is OpenXmlLeafTextElement) { SimpleContentComplexTypeValidator.Validate(validationContext); } 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 (theElement.ParticleConstraint != null) { // composite element CompositeComplexTypeValidator.Validate(validationContext); } 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> /// 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 attributes on AlternateContent, Choice and Fallback element. /// </summary> /// <param name="validationContext"></param> /// <param name="acElement">The element to be validated.</param> private static void ValidateMcAttributesOnAcb(ValidationContext validationContext, OpenXmlElement acElement) { ValidationErrorInfo errorInfo; // AlternateContent elements might include the attributes Ignorable, MustUnderstand, ProcessContent, PreserveElements, and PreserveAttributes // These attributes’ qualified names shall be prefixed when associated with an AlternateContent / Choice / Fallback element. // A markup consumer shall generate an error if it encounters an unprefixed attribute name associated with an AlternateContent element. if (acElement.ExtendedAttributes != null) { foreach (var exAttribute in acElement.ExtendedAttributes) { if (string.IsNullOrEmpty(exAttribute.Prefix)) { // error on any unprefixed attributes errorInfo = validationContext.ComposeMcValidationError(acElement, ValidationResources.MC_ErrorOnUnprefixedAttributeName, exAttribute.XmlQualifiedName.ToString()); validationContext.EmitError(errorInfo); } // Markup consumers shall generate an error if they encounter the xml:lang or xml:space attributes on an AlternateContent element. // Markup consumers shall generate an error if they encounter the xml:lang or xml:space attributes on a Choice element, regardless of whether the element is preceded by a selected Choice element. // Markup consumers shall generate an error if they encounter the xml:lang or xml:space attributes on a Fallback element, regardless of whether the element is preceded by a selected Choice element. if (IsXmlSpaceOrXmlLangAttribue(exAttribute)) { // report error. errorInfo = validationContext.ComposeMcValidationError(acElement, "MC_InvalidXmlAttribute", acElement.LocalName); validationContext.EmitError(errorInfo); } } } // validate MC attribues (Ignorable, PreserveElements, etc.) of this element. CompatibilityRuleAttributesValidator.ValidateMcAttributes(validationContext); AlternateContentChoice choice = acElement as AlternateContentChoice; if (choice != null) { // All Choice elements shall have a Requires attribute whose value contains a whitespace-delimited list of namespace prefixes if (choice.Requires == null) { // report error errorInfo = validationContext.ComposeMcValidationError(acElement, "MC_MissedRequiresAttribute"); validationContext.EmitError(errorInfo); } else { var prefixes = new ListValue <StringValue>(); prefixes.InnerText = choice.Requires; foreach (var prefix in prefixes.Items) { var ignorableNamespace = choice.LookupNamespace(prefix); if (string.IsNullOrEmpty(ignorableNamespace)) { // report error, the prefix is not defined. errorInfo = validationContext.ComposeMcValidationError(choice, "MC_InvalidRequiresAttribute", choice.Requires); validationContext.EmitError(errorInfo); } } } } }