public override ValidationErrorInfo Validate(ValidationContext context) { string minAttributeValue = context.Element.GetAttributeValueEx(_minAttributeLocalName, _minAttributeNamesapce); double minValue; //If value cannot be converted into double, that means attribute type is not correct. //That's job of schema validation, semantic validation will do nothing to avoid throw duplicated error. if (!double.TryParse(minAttributeValue, out minValue)) { return null; } string maxAttributeValue = context.Element.GetAttributeValueEx(_maxAttributeLocalName, _maxAttributeNamesapce); double maxValue; //If value cannot be converted into double, that means attribute type is not correct. //That's job of schema validation, semantic validation will do nothing to avoid throw duplicated error. if (!double.TryParse(maxAttributeValue, out maxValue)) { return null; } if (minValue <= maxValue) { return null; } string errorId = ""; //todo: add error id string errorMessage = ""; //todo: add error message return new ValidationErrorInfo() { Id = errorId, ErrorType = ValidationErrorType.Semantic, Node = context.Element, Description = errorMessage }; }
public override ValidationErrorInfo Validate(ValidationContext context) { if (_values == null) { return null; } OpenXmlSimpleType attributeValue = context.Element.Attributes[_attribute]; //if the attribute is omited, semantic validation will do nothing if (attributeValue == null || string.IsNullOrEmpty(attributeValue.InnerText)) { return null; } if (_values.Where(v => string.Compare(v, attributeValue.InnerText, !_caseSensitive, System.Globalization.CultureInfo.InvariantCulture) == 0).Count() == 0) { _values.Add(attributeValue.InnerText); return null; } return new ValidationErrorInfo() { Id = "Sem_UniqueAttributeValue", ErrorType = ValidationErrorType.Semantic, Node = context.Element, Description = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sem_UniqueAttributeValue, GetAttributeQualifiedName(context.Element, _attribute), attributeValue.InnerText) }; }
protected static OpenXmlPart GetReferencedPart(ValidationContext context, string path) { if (path == ".") { return context.Part; } string[] parts = path.Split('/'); if (string.IsNullOrEmpty(parts[0])) { return GetPartThroughPartPath(context.Package.Parts, parts.Skip(1).ToArray()); //absolute path } else if (parts[0] == "..") { IEnumerable<OpenXmlPart> iterator = new OpenXmlPackagePartIterator(context.Package); IEnumerable<OpenXmlPart> refParts = iterator.Where(p => p.Parts.Select(r => r.OpenXmlPart.PackagePart.Uri) .Contains(context.Part.PackagePart.Uri)); Debug.Assert(refParts.Count() == 1); return refParts.First(); } else { return GetPartThroughPartPath(context.Part.Parts, parts); //relative path } }
/// <summary> /// Try match the particle. /// </summary> /// <param name="particleMatchInfo"></param> /// <param name="validationContext">The context information for validation.</param> public override void TryMatch(ParticleMatchInfo particleMatchInfo, ValidationContext validationContext) { // maxOccurs of xsd:any can only be 1 Debug.Assert(this.ParticleConstraint.MaxOccurs == 1); this.TryMatchOnce(particleMatchInfo, validationContext); }
public override ValidationErrorInfo Validate(ValidationContext context) { OpenXmlSimpleType attributeValue = context.Element.Attributes[_attribute]; //if the attribute is omited, semantic validation will do nothing if (attributeValue == null || string.IsNullOrEmpty(attributeValue.InnerText)) { return null; } int index; if (!int.TryParse(attributeValue, out index)) { return null; //if attribute is not int, schema validation will cover this error. } if (index < GetRefElementCount(context) + _indexBase) { return null; } return new ValidationErrorInfo() { Id = "Sem_MissingIndexedElement", ErrorType = ValidationErrorType.Semantic, Node = context.Element, RelatedPart = this._relatedPart, RelatedNode = null, Description = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sem_MissingIndexedElement, _refElementName,context.Element.LocalName, GetAttributeQualifiedName(context.Element, _attribute), _relatedPart == null? _refPartType : _relatedPart.PackagePart.Uri.ToString(), index) }; }
public override ValidationErrorInfo Validate(ValidationContext context) { OpenXmlSimpleType attributeValue = context.Element.Attributes[_refAttribute]; if (attributeValue == null || string.IsNullOrEmpty(attributeValue.InnerText)) { return null; } if (GetReferencedAttributes(context).Contains(attributeValue.InnerText)) { return null; } return new ValidationErrorInfo() { Id = "Sem_MissingReferenceElement", ErrorType = ValidationErrorType.Semantic, Node = context.Element, RelatedPart = this._relatedPart, RelatedNode = null, Description = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sem_MissingReferenceElement, _elementName, context.Element.LocalName, GetAttributeQualifiedName(context.Element, _refAttribute), _relatedPart == null ? _partPath : _relatedPart.PackagePart.Uri.ToString(), attributeValue.InnerText) }; }
public override ValidationErrorInfo Validate(ValidationContext context) { OpenXmlSimpleType attributeValue = context.Element.Attributes[_rIdAttribute]; //if the attribute is omited, semantic validation will do nothing if (attributeValue == null || string.IsNullOrEmpty(attributeValue.InnerText)) { return null; } if (context.Part.PackagePart.RelationshipExists(attributeValue.InnerText)) { return null; } else { string errorDescription = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sem_InvalidRelationshipId, attributeValue, GetAttributeQualifiedName(context.Element, _rIdAttribute)); return new ValidationErrorInfo() { Id = "Sem_InvalidRelationshipId", ErrorType = ValidationErrorType.Semantic, Node = context.Element, Description = errorDescription }; } }
public override ValidationErrorInfo Validate(ValidationContext context) { OpenXmlSimpleType attributeValue = context.Element.Attributes[_attribute]; //if the attribute is omited, semantic validation will do nothing if (attributeValue == null || string.IsNullOrEmpty(attributeValue.InnerText)) { return null; } Regex regex = new Regex(this._pattern); if (regex.IsMatch(attributeValue.InnerText)) { return null; } string subMsg = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sch_PatternConstraintFailed, _pattern); return new ValidationErrorInfo() { Id = "Sem_AttributeValueDataTypeDetailed", ErrorType = ValidationErrorType.Schema, Node = context.Element, Description = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sem_AttributeValueDataTypeDetailed, GetAttributeQualifiedName(context.Element, _attribute), attributeValue.InnerText, subMsg) }; }
public void Validate(ValidationContext validationContext) { Debug.Assert(validationContext != null); Debug.Assert(validationContext.Element != null); this._stopValidating = false; ValidationTraverser.ValidatingTraverse(validationContext, this.ValidateElement, OnContextValidationFinished, this.StopSignal); }
private void ValidateElement(ValidationContext context) { if (_curReg != null) { foreach (var error in _curReg.CheckConstraints(context)) { context.EmitError(error); } } }
/// <summary> /// Try match the particle once. /// </summary> /// <param name="particleMatchInfo"></param> /// <param name="validationContext">The context information for validation.</param> public override void TryMatchOnce(ParticleMatchInfo particleMatchInfo, ValidationContext validationContext) { Debug.Assert(!(particleMatchInfo.StartElement is OpenXmlMiscNode)); var next = particleMatchInfo.StartElement; particleMatchInfo.LastMatchedElement = null; particleMatchInfo.Match = ParticleMatch.Nomatch; ParticleConstraint childConstraint; int constraintIndex = 0; int constraintTotal = this.ParticleConstraint.ChildrenParticles.Length; while (constraintIndex < constraintTotal && next != null) { childConstraint = this.ParticleConstraint.ChildrenParticles[constraintIndex]; // Use Reset() instead of new() to avoid heavy memory alloction and GC. _childMatchInfo.Reset(next); childConstraint.ParticleValidator.TryMatch(_childMatchInfo, validationContext); // if the _childMatchInfo.StartElement is changed, it means this method of this object is called more than once on the stack. Debug.Assert(_childMatchInfo.StartElement == next); switch (_childMatchInfo.Match) { case ParticleMatch.Nomatch: // continue trying match next child constraint. constraintIndex++; break; case ParticleMatch.Matched: particleMatchInfo.Match = ParticleMatch.Matched; particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; return; case ParticleMatch.Partial: // partial match, incomplete children. particleMatchInfo.Match = ParticleMatch.Partial; particleMatchInfo.LastMatchedElement = _childMatchInfo.LastMatchedElement; if (validationContext.CollectExpectedChildren) { particleMatchInfo.SetExpectedChildren(_childMatchInfo.ExpectedChildren); } return; } } // no match Debug.Assert(particleMatchInfo.Match == ParticleMatch.Nomatch); return; }
public override ValidationErrorInfo Validate(ValidationContext context) { OpenXmlSimpleType attributeValue = context.Element.Attributes[_requiredAttribute]; if (attributeValue != null) { return null; } OpenXmlSimpleType conditionAttributeValue = context.Element.Attributes[_conditionAttribute]; if (conditionAttributeValue == null) { return null; } foreach (string value in _values) { if (AttributeValueEquals(conditionAttributeValue, value, false)) { string valueString = "'" + _values[0] + "'"; if (_values.Length > 1) { for (int i = 1; i < _values.Length - 1; i++) { valueString += ", '" + _values[i] + "'"; } valueString += " or '" + _values[_values.Length - 1] + "'"; } return new ValidationErrorInfo() { Id = "Sem_AttributeRequiredConditionToValue", ErrorType = ValidationErrorType.Semantic, Node = context.Element, Description = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sem_AttributeRequiredConditionToValue, GetAttributeQualifiedName(context.Element, _requiredAttribute), GetAttributeQualifiedName(context.Element, _conditionAttribute), valueString) }; } } return null; }
public override ValidationErrorInfo Validate(ValidationContext context) { OpenXmlElement parent = context.Element.Parent; if (parent == null) { return null; } if (parent.GetType() == this._parentType ^ !this._isValid) //TODO: (junzha) need to take ac-block into account. { return null; } return new ValidationErrorInfo() { Id = "", ErrorType = ValidationErrorType.Semantic, Node = context.Element, Description = "" }; }
public override ValidationErrorInfo Validate(ValidationContext context) { if (context.Element.Attributes[_attribute] != null) { return null; } return new ValidationErrorInfo() { Id = "Sem_MissRequiredAttribute", ErrorType = ValidationErrorType.Schema, Node = context.Element, Description = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sch_MissRequiredAttribute, GetAttributeQualifiedName(context.Element, _attribute)) }; }
// *********************************************************** //<xsd:group ref="..." /> is valid under <xsd:complexType> //<xsd:complexType name="CT_HdrFtr"> // <xsd:group ref="EG_BlockLevelElts" minOccurs="1" maxOccurs="unbounded" /> //</xsd:complexType> // *********************************************************** ///// <summary> ///// Be called on root particle of complex type. ///// </summary> ///// <param name="validationContext"></param> ///// <returns></returns> //internal override SchemaValidationResult Validate(ValidationContext validationContext) //{ // throw new InvalidOperationException(); //} /// <summary> /// Try match the particle once. /// </summary> /// <param name="particleMatchInfo"></param> /// <param name="validationContext">The context information for validation.</param> public override void TryMatchOnce(ParticleMatchInfo particleMatchInfo, ValidationContext validationContext) { Debug.Assert(!(particleMatchInfo.StartElement is OpenXmlMiscNode)); // group only contains xsd:all, xsd:choice or xsd:sequence Debug.Assert(this.ParticleConstraint.ChildrenParticles.Length == 1); var childParticle = this.ParticleConstraint.ChildrenParticles[0]; Debug.Assert(childParticle.ParticleType == ParticleType.All || childParticle.ParticleType == ParticleType.Choice || childParticle.ParticleType == ParticleType.Sequence); childParticle.ParticleValidator.TryMatch(particleMatchInfo, validationContext); return; }
public override void ClearState(ValidationContext context) { if (context == null) //initialize before validating { _stateStack.Clear(); _values = _partLevel ? new List<string>() : null; } else //unique scope element reached { if (_values != null) { _stateStack.Push(_values); } _reg.AddCallBackMethod(context.Element, this.AdjustState); _values = new List<string>(); } }
public override ValidationErrorInfo Validate(ValidationContext context) { OpenXmlSimpleType attributeValue = context.Element.Attributes[_attribute]; if (attributeValue == null) { return null; } double val; if (!GetAttrNumVal(attributeValue, out val)) { return null; } OpenXmlSimpleType otherAttributeValue = context.Element.Attributes[_otherAttribute]; if (otherAttributeValue == null) { return null; } double otherVal; if (!GetAttrNumVal(otherAttributeValue, out otherVal)) { return null; } if (val < otherVal && !_canEqual || val <= otherVal && _canEqual) { return null; } string format = _canEqual ? ValidationResources.Sem_AttributeValueLessEqualToAnother : ValidationResources.Sem_AttributeValueLessEqualToAnotherEx; return new ValidationErrorInfo() { Id = "Sem_AttributeValueLessEqualToAnother", ErrorType = ValidationErrorType.Semantic, Node = context.Element, Description = string.Format(System.Globalization.CultureInfo.CurrentUICulture, format, GetAttributeQualifiedName(context.Element, _attribute), attributeValue.InnerText, GetAttributeQualifiedName(context.Element, _otherAttribute), otherAttributeValue.InnerText) }; }
public void AttributeMinMaxConstraintTest() { Excel.Column column = new Excel.Column(); ValidationContext context = new ValidationContext() { Element = column }; AttributeMinMaxConstraint constraint = new AttributeMinMaxConstraint("", "min", "", "max") ; column.Max = 2; column.Min = 1; Assert.Null(constraint.Validate(context)); //max > min, should pass validation column.Max = 2; column.Min = 2; Assert.Null(constraint.Validate(context)); //max == min, should pass validation column.Max = 2; column.Min = 3; Assert.NotNull(constraint.Validate(context)); //max < min, validation should be failed. }
public override ValidationErrorInfo Validate(ValidationContext context) { OpenXmlSimpleType attributeValue = context.Element.Attributes[_attribute]; if (attributeValue == null || string.IsNullOrEmpty(attributeValue.InnerText)) { return null; } string actualType = _type; IEnumerable<ExternalRelationship> rels = context.Part.ExternalRelationships.Where(r => r.Id == attributeValue.InnerText); if (rels.Count() == 0) { IEnumerable<IdPartPair> pairs = context.Part.Parts.Where(p => p.RelationshipId == attributeValue.InnerText); if (pairs.Count() != 0) { Debug.Assert(pairs.Count() == 1); actualType = pairs.First().OpenXmlPart.RelationshipType; } } else { Debug.Assert(rels.Count() == 1); actualType = rels.First().RelationshipType; } if (actualType == _type) { return null; } return new ValidationErrorInfo() { Id = "Sem_IncorrectRelationshipType", ErrorType = ValidationErrorType.Semantic, Node = context.Element, Description = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sem_IncorrectRelationshipType, actualType, GetAttributeQualifiedName(context.Element, _attribute), this._type) }; }
/// <summary> /// Validate the DOM tree under the specified OpenXmlElement. /// </summary> /// <param name="schemaValidator">The schemaValidator.</param> /// <param name="openxmlElement">The root of the sub tree.</param> /// <returns>Returns the validation result in ValidationResult.</returns> /// <remarks> /// Only schema validating. /// </remarks> internal static ValidationResult Validate(this SchemaValidator schemaValidator, OpenXmlElement openxmlElement) { Debug.Assert(openxmlElement != null); var validationResult = new ValidationResult(); Debug.Assert(!(openxmlElement is OpenXmlUnknownElement || openxmlElement is OpenXmlMiscNode)); // Can not just validate AlternateContent / Choice / Fallback // Debug.Assert(!(openxmlElement is AlternateContent)) Debug.Assert(!(openxmlElement is AlternateContentChoice || openxmlElement is AlternateContentFallback)); var validationContext = new ValidationContext(); validationContext.ValidationErrorEventHandler += validationResult.OnValidationError; validationContext.Element = openxmlElement; schemaValidator.Validate(validationContext); return validationResult; }
/// <summary> /// Validate the DOM tree under the specified OpenXmlElement in the context. /// </summary> /// <param name="validationContext"></param> internal void Validate(ValidationContext validationContext) { Debug.Assert(validationContext != null); Debug.Assert(validationContext.Element != null); this._stopValidating = false; var openxmlElement = validationContext.Element; Debug.Assert(!(openxmlElement is OpenXmlUnknownElement || openxmlElement is OpenXmlMiscNode)); // Can not just validate AlternateContent / Choice / Fallback // Debug.Assert(!(openxmlElement is AlternateContent)) Debug.Assert(!(openxmlElement is AlternateContentChoice || openxmlElement is AlternateContentFallback)); ValidationTraverser.ValidatingTraverse(validationContext, this.ValidateElement, null, this.StopSignal); // validationContext.Element = openxmlElement; return; }
public override ValidationErrorInfo Validate(ValidationContext context) { bool attribute1Exist = context.Element.GetAttributeValueEx(this._attribute1LocalName, this._attribute1Namespace) != null; bool attribute2Exist = context.Element.GetAttributeValueEx(this._attribute2LocalName, this._attribute2Namespace) != null; //if (attribute1Exist) //{ // this.MissedAttribute = this._attribute2LocalName; // this.ExistAttribute = this._attribute1LocalName; //} //else //{ // this.MissedAttribute = this._attribute1LocalName; // this.ExistAttribute = this._attribute2LocalName; //} if (!(attribute1Exist ^ attribute2Exist)) { return null; } return new ValidationErrorInfo() { Id = "", ErrorType = ValidationErrorType.Semantic, Node = context.Element, Description = "" }; }
public override ValidationErrorInfo Validate(ValidationContext context) { OpenXmlSimpleType attributeValue = context.Element.Attributes[_attribute]; //if the attribute is omited, semantic validation will do nothing if (attributeValue == null || string.IsNullOrEmpty(attributeValue.InnerText)) { return null; } bool valueSetContains = false; foreach (string value in _valueSet) { if (AttributeValueEquals(attributeValue, value, false)) { valueSetContains = true; } } if (!this._isValidValueSet ^ valueSetContains) { return null; } string subMsg = ValidationResources.Sch_EnumerationConstraintFailed; string errorDescription = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sem_AttributeValueDataTypeDetailed, GetAttributeQualifiedName(context.Element, _attribute), attributeValue, subMsg); return new ValidationErrorInfo() { Id = "Sem_AttributeValueDataTypeDetailed", ErrorType = ValidationErrorType.Schema, Node = context.Element, Description = errorDescription }; }
public override ValidationErrorInfo Validate(ValidationContext context) { OpenXmlSimpleType attribute = context.Element.Attributes[_attribute]; //if the attribute is omited, semantic validation will do nothing if (attribute == null) { return null; } string attributeValue = attribute.InnerText == null ? string.Empty : attribute.InnerText; string subMsg = null; if (attributeValue.Length < this._minLength) { subMsg = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sem_MinLengthConstraintFailed, _minLength); } else if (attributeValue.Length > this._maxLength) { subMsg = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sem_MaxLengthConstraintFailed, _maxLength); } if (subMsg == null) { return null; } return new ValidationErrorInfo() { Id = "Sem_AttributeValueDataTypeDetailed", ErrorType = ValidationErrorType.Schema, Node = context.Element, Description = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sem_AttributeValueDataTypeDetailed, GetAttributeQualifiedName(context.Element, _attribute), attributeValue, subMsg) }; }
public override ValidationErrorInfo Validate(ValidationContext context) { string attributes = string.Empty; string existAttribute = string.Empty; string existAttribute2 = string.Empty; foreach (byte attribute in _attributes) { attributes += "," + GetAttributeQualifiedName(context.Element, attribute); if (context.Element.Attributes[attribute] != null) { if (!string.IsNullOrEmpty(existAttribute2)) { existAttribute += "," + existAttribute2; } existAttribute2 = GetAttributeQualifiedName(context.Element, attribute).ToString(); } } if (string.IsNullOrEmpty(existAttribute)) { return null; } return new ValidationErrorInfo() { Id = "Sem_AttributeMutualExclusive", ErrorType = ValidationErrorType.Semantic, Node = context.Element, Description = string.Format(System.Globalization.CultureInfo.CurrentUICulture, ValidationResources.Sem_AttributeMutualExclusive, existAttribute.Substring(1), existAttribute2, attributes.Substring(1)) }; }
/// <summary> /// Validate QName list in PreserveElements, PreserveAttributes, ProcessContent. /// </summary> /// <param name="qnameList">The QName list to be validated.</param> /// <param name="ignorableNamespaces">The ignorable namespaces.</param> /// <param name="validationContext"></param> /// <returns>The QName that is not valid.</returns> internal static string ValidateQNameList(string qnameList, HashSet<string> ignorableNamespaces, ValidationContext validationContext) { Debug.Assert(!string.IsNullOrEmpty(qnameList)); var qnames = new ListValue<StringValue>(); qnames.InnerText = qnameList; foreach (var qname in qnames.Items) { // must be QName var items = qname.Value.Split(':'); if (items.Length != 2) { return qname; } // Prefix must be already defined. var attributeNamesapce = validationContext.Element.LookupNamespace(items[0]); if (string.IsNullOrEmpty(attributeNamesapce)) { return qname; } // The namespace must be identified by the Ignorable attribute at the same element. if (!ignorableNamespaces.Contains(attributeNamesapce)) { return qname; } } return null; }
/// <summary> /// Validate ACB syntax - AlternateContent, Choice, Fallback and their attributes. /// </summary> /// <param name="validationContext"></param> internal static void Validate(ValidationContext validationContext) { AlternateContent acElement = (AlternateContent)validationContext.Element; // Validate MC attribute on AlternateContent ValidateMcAttributesOnAcb(validationContext, acElement); int status = 0; ValidationErrorInfo errorInfo; if (acElement.ChildElements.Count == 0) { // Rule: An AlternateContent element shall contain one or more Choice child elements errorInfo = validationContext.ComposeMcValidationError(acElement, "Sch_IncompleteContentExpectingComplex", ValidationResources.MC_ShallContainChoice); validationContext.EmitError(errorInfo); } OpenXmlElement child; child = acElement.GetFirstNonMiscElementChild(); while (child != null) { if (child is AlternateContent) { // Rule: An AlternateContent element shall not be the child of an AlternateContent element. errorInfo = validationContext.ComposeMcValidationError(acElement, "Sch_InvalidElementContentExpectingComplex", child.XmlQualifiedName.ToString(), ValidationResources.MC_ShallNotContainAlternateContent); validationContext.EmitError(errorInfo); } else { switch (status) { case 0: // expect a Choice if (child is AlternateContentChoice) { // validate the MC attributes on Choice ValidateMcAttributesOnAcb(validationContext, child); status = 1; } else { // Rule: An AlternateContent element shall contain one or more Choice child elements errorInfo = validationContext.ComposeMcValidationError(acElement, "Sch_IncompleteContentExpectingComplex", ValidationResources.MC_ShallContainChoice); validationContext.EmitError(errorInfo); if (child is AlternateContentFallback) { // validate the MC attributes on Fallback ValidateMcAttributesOnAcb(validationContext, child); } } break; case 1: // Already one Choice, expect Choice or Fallback if (child is AlternateContentChoice) { // validate the MC attributes on Choice ValidateMcAttributesOnAcb(validationContext, child); status = 1; } else if (child is AlternateContentFallback) { // validate the MC attributes on Fallback ValidateMcAttributesOnAcb(validationContext, child); status = 2; } else { errorInfo = validationContext.ComposeMcValidationError(acElement, "Sch_InvalidElementContentExpectingComplex", child.XmlQualifiedName.ToString(), ValidationResources.MC_ShallContainChoice); validationContext.EmitError(errorInfo); } break; case 2: // Already one Fallback. Can not have more than one Fallback errorInfo = validationContext.ComposeMcValidationError(acElement, "Sch_InvalidElementContentExpectingComplex", child.XmlQualifiedName.ToString(), ValidationResources.MC_ShallContainChoice); validationContext.EmitError(errorInfo); break; } } child = child.GetNextNonMiscElementSibling(); } return; }
/// <summary> /// Validate compatibility rule attributes - Ignorable, ProcessContent, PreserveElements, PreserveAttributes, MustUnderstand. /// </summary> /// <param name="validationContext">The validation context.</param> internal static void ValidateMcAttributes(ValidationContext validationContext) { var element = validationContext.Element; if (element.MCAttributes == null) { return; } HashSet<string> ignorableNamespaces = null; ValidationErrorInfo errorInfo; if (element.MCAttributes != null) { // validate Ignorable attribute if (!string.IsNullOrEmpty(element.MCAttributes.Ignorable)) { ignorableNamespaces = new HashSet<string>(); // rule: the prefix must already be defined. var prefixes = new ListValue<StringValue>(); prefixes.InnerText = element.MCAttributes.Ignorable; foreach (var prefix in prefixes.Items) { var ignorableNamespace = element.LookupNamespace(prefix); if (string.IsNullOrEmpty(ignorableNamespace)) { // error, the prefix is not defined. errorInfo = validationContext.ComposeMcValidationError(element, "MC_InvalidIgnorableAttribute", element.MCAttributes.Ignorable); validationContext.EmitError(errorInfo); } else { ignorableNamespaces.Add(ignorableNamespace); } } } // validate PreserveAttributes attribute if (!string.IsNullOrEmpty(element.MCAttributes.PreserveAttributes)) { // The ProcessAttributes attribute value shall not reference any attribute name that does not belong to a namespace // that is identified by the Ignorable attribute of the same element. if (ignorableNamespaces == null) { // must have Ignorable on same element. errorInfo = validationContext.ComposeMcValidationError(element, "MC_InvalidPreserveAttributesAttribute", element.MCAttributes.PreserveAttributes); validationContext.EmitError(errorInfo); } else { string errorQName = ValidateQNameList(element.MCAttributes.PreserveAttributes, ignorableNamespaces, validationContext); if (!string.IsNullOrEmpty(errorQName)) { errorInfo = validationContext.ComposeMcValidationError(element, "MC_InvalidPreserveAttributesAttribute", element.MCAttributes.PreserveAttributes); validationContext.EmitError(errorInfo); } } } // validate PreserveElements attribute if (!string.IsNullOrEmpty(element.MCAttributes.PreserveElements)) { // The ProcessAttributes attribute value shall not reference any attribute name that does not belong to a namespace // that is identified by the Ignorable attribute of the same element. if (ignorableNamespaces == null) { // must have Ignorable on same element. errorInfo = validationContext.ComposeMcValidationError(element, "MC_InvalidPreserveElementsAttribute", element.MCAttributes.PreserveElements); validationContext.EmitError(errorInfo); } else { string errorQName = ValidateQNameList(element.MCAttributes.PreserveElements, ignorableNamespaces, validationContext); if (!string.IsNullOrEmpty(errorQName)) { errorInfo = validationContext.ComposeMcValidationError(element, "MC_InvalidPreserveElementsAttribute", element.MCAttributes.PreserveElements); validationContext.EmitError(errorInfo); } } } // validate ProcessContent attribute if (!string.IsNullOrEmpty(element.MCAttributes.ProcessContent)) { // The ProcessAttributes attribute value shall not reference any attribute name that does not belong to a namespace // that is identified by the Ignorable attribute of the same element. if (ignorableNamespaces == null) { // must have Ignorable on same element. errorInfo = validationContext.ComposeMcValidationError(element, "MC_InvalidProcessContentAttribute", element.MCAttributes.ProcessContent); validationContext.EmitError(errorInfo); } else { string errorQName = ValidateQNameList(element.MCAttributes.ProcessContent, ignorableNamespaces, validationContext); if (!string.IsNullOrEmpty(errorQName)) { errorInfo = validationContext.ComposeMcValidationError(element, "MC_InvalidProcessContentAttribute", element.MCAttributes.ProcessContent); validationContext.EmitError(errorInfo); } } foreach (var exAttribute in element.ExtendedAttributes) { // Markup consumers that encounter a non-ignored element that has an xml:lang or xml:space attribute and is also identified by a ProcessContent attribute value might generate an error. if (AlternateContentValidator.IsXmlSpaceOrXmlLangAttribue(exAttribute)) { // report error. errorInfo = validationContext.ComposeMcValidationError(element, "MC_InvalidXmlAttributeWithProcessContent"); validationContext.EmitError(errorInfo); } } } if (!string.IsNullOrEmpty(element.MCAttributes.MustUnderstand)) { // TODO: MustUnderstand // A markup consumer that does not understand these identified namespaces shall not continue to process the markup document // rule: the prefix must already be defined. var prefixes = new ListValue<StringValue>(); prefixes.InnerText = element.MCAttributes.MustUnderstand; foreach (var prefix in prefixes.Items) { var mustunderstandNamespace = element.LookupNamespace(prefix); if (string.IsNullOrEmpty(mustunderstandNamespace)) { // report error, the prefix is not defined. errorInfo = validationContext.ComposeMcValidationError(element, "MC_InvalidMustUnderstandAttribute", element.MCAttributes.MustUnderstand); validationContext.EmitError(errorInfo); } } } } }
/// <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); } } } } }
private List<string> GetReferencedAttributes(ValidationContext context) { if (_referencedAttributes == null) { _referencedAttributes = new List<string>(); OpenXmlPart part = GetReferencedPart(context, _partPath); this._relatedPart = part; if (part != null) { ValidationContext partContext = new ValidationContext(); partContext.FileFormat = context.FileFormat; partContext.Package = context.Package; partContext.Part = part; partContext.Element = part.RootElement; ValidationTraverser.ValidatingTraverse(partContext, this.ElementTraverse, null, null); } } return _referencedAttributes; }