public bool IsMatch(AttributeClass attr) { MatchResult = ""; if (attr == null) { throw new Exception("Matching: проверка шаблона " + this.Id + " для null"); } if (attr.Id != "" && this.Id != "" && attr.Id != this.Id) { return(false); } if (attr.DataType != this.DataType) { MatchResult = "неверный тип значения " + Id + ": " + attr.DataType.ToString() + "\n"; return(false); } bool success = false; switch (DataType) { case AttributeDataType.Bool: success = IsValueMatch(attr.AsBool); break; case AttributeDataType.Double: success = IsValueMatch(attr.AsDouble); break; case AttributeDataType.DateTime: success = IsValueMatch(attr.AsDateTime); break; case AttributeDataType.Long: success = IsValueMatch(attr.AsLong); break; case AttributeDataType.String: success = IsValueMatch(attr.AsString); break; default: throw new ArgumentException("Некорректный тип атрибута для сравнения " + DataType.ToString()); } if (!success) { MatchResult = "неверное значение"; } return(success); }
/// <summary> /// Функция возвращает истину, если сопоставление атрибутов документа шаблону успешно. /// Правило сопоставления зависит от значения поля AttributesCompareMode. /// Возможны варианты: /// CompareMode.ExistsInDocument - проверка наличия соответствующего атрибута для каждого шаблона атрибута; /// CompareMode.ExistsInPattern - проверка наличия шаблона атрибута для каждого атрибута документа; /// CompareMode.Equality - проверка полного соответствия атрибутов шаблонам /// </summary> /// <param name="doc">проверяемый документ</param> /// <param name="amplifyIfMatch">указывает необходимость заполнения значений</param> /// <returns></returns> private bool IsAttributesMatch(DocumentClass doc, bool amplifyIfMatch = false) { //Флаг успеха сравнения bool success = true; //Если в шаблоне документа не было заявлено атрибутов, то проверка считается успешной if (AttributesPatterns.Count == 0) { return(true); } //Временная коллекция для сравнения. Содержит существующие и предполагаемые атрибуты документа List <AttributeClass> attributes = new List <AttributeClass>(); //Если строка шаблона не пустая, то пытаемся извлечь атрибуты из имени и добавляем во временную коллецию if (AttributesPatternString != "") { attributes = AttributesFromString(doc.Name, AttributesPatternString); } //Если у документа уже есть атрибуты, то добавляем их во временную коллекцию attributes.AddRange(doc.Attributes); //Проверяем наличие в документе атрибутов, описанных в шаблоне if (AttributesCompareMode == CompareMode.ExistsInDocument) { foreach (AttributePatternClass ptrn in this.AttributesPatterns) { AttributeClass attr = attributes.FirstOrDefault(a => ptrn.IsMatch(a)); if (attr == null) { result.Text += "\nАтрибут не найден: '" + ptrn.Id + "'"; success = false; } else { result.Text += ptrn.MatchResult; } } } //Проверяем наличие в шаблоне атрибутов, описанных в документе else if (AttributesCompareMode == CompareMode.ExistsInPattern) { //Каждый из атрибутов документа проверяем на соответствие какому-либо шаблону foreach (AttributeClass attr in attributes) { //Ищем шаблон атрибута, которому удовлетворяет attr AttributePatternClass ptrn = AttributesPatterns.FirstOrDefault(a => a.IsMatch(attr)); //Если условия не выполнены if (ptrn == null) { result.Text += "\nАтрибут не предусмотрен: '" + attr.Id + "=" + attr.AsString + "' {" + AttributesPatterns. Where(p => p.MatchResult != ""). Aggregate("", (cur, next) => cur == "" ? cur + next : cur + "; " + next) + "}"; success = false; } else { result.Text += ptrn.MatchResult; } } } //Проверяем взаимнооднозначное соответствие атрибутов документа атрибутам шаблона else if (AttributesCompareMode == CompareMode.Equality) { //Временная коллекция шаблонов атрибутов List <AttributePatternClass> patterns = new List <AttributePatternClass>(this.AttributesPatterns); foreach (AttributeClass attr in attributes) { //Ищем шаблон атрибута, которому удовлетворяет attr AttributePatternClass ptrn = patterns.FirstOrDefault(a => a.IsMatch(attr)); //Если такой атрибут в шаблоне отсутствует if (ptrn == null) { result.Text += "\nАтрибут не предусмотрен: '" + attr.Id + "=" + attr.AsString + "' {" + AttributesPatterns. Where(p => p.MatchResult != ""). Aggregate("", (cur, next) => cur == "" ? cur + next : cur + "; " + next) + " }"; success = false; } else { //Если шаблон атрибута найден, то при следующей проверке он не используется patterns.Remove(ptrn); } } //Если все атрибуты документа проверены и для каждого нашелся свой шаблон, то проверка успешна success = success && (patterns.Count == 0); } //Дополняем описание атрибутов, если сопоставление успешно if (amplifyIfMatch && success) { doc.Attributes = attributes; } return(success); }