private Element GetTagObject(Element element, string line, ILineValueExtractor lineValueExtractor) { var tagElement = (from childTag in element.Elements.Where(x => x.ElementType == ElementType.Tag) let childTagValue = lineValueExtractor.Extract(line, childTag) where childTagValue.IsFound && childTagValue.Value == childTag.Tag select childTag).FirstOrDefault(); return(tagElement); }
private void ParseWithTag <T>(Element parentElement, Element element, object parentInstance, PropertyInfo listPropertyInfo, Result <T> result, string[] lines, ILineValueExtractor lineValueExtractor, ref int linePosition, ref bool continueParsing) { for (var i = linePosition; i < lines.Length; i++) { linePosition = i; var parentElementTagValue = lineValueExtractor.Extract(lines[i], parentElement); if (parentElementTagValue.IsFound && parentElementTagValue.Value == parentElement.Tag) { linePosition--; return; } var tagValue = lineValueExtractor.Extract(lines[i], element); if (!tagValue.IsFound || string.IsNullOrEmpty(tagValue.Value)) { result.Errors.Add($"Line {i} does not contain any valid tag."); continueParsing = false; return; } if (tagValue.Value != element.Tag) { var tagElement = GetTagObject(element, lines[i], lineValueExtractor); if (tagElement != null) { var lastInstance = GetLastFromList(element.Type, listPropertyInfo, parentInstance); var childListPropertyInfo = lastInstance.GetType().GetProperty(tagElement.Name); if (childListPropertyInfo.GetValue(lastInstance) == null) { childListPropertyInfo.SetValue(lastInstance, Activator.CreateInstance(childListPropertyInfo.PropertyType)); } ParseWithTag(element, tagElement, lastInstance, childListPropertyInfo, result, lines, lineValueExtractor, ref linePosition, ref continueParsing); return; } linePosition--; return; } var newObject = Activator.CreateInstance(element.Type); listPropertyInfo.PropertyType.GetMethod("Add").Invoke(listPropertyInfo.GetValue(parentInstance), new[] { newObject }); var propertyElements = element.Elements.Where(child => child.ElementType == ElementType.Property).ToList(); foreach (var propertyElement in propertyElements) { var propertyValue = lineValueExtractor.Extract(lines[i], propertyElement, element); if ((!propertyValue.IsFound || string.IsNullOrEmpty(propertyValue.Value)) && propertyElement.Required) { result.Errors.Add($"Property {propertyElement.Name} is missing at Line {i}."); } var propertyInfo = element.Type.GetProperty(propertyElement.Name, BindingFlags.Public | BindingFlags.Instance); var isSet = _valueSetter.Set(propertyInfo, propertyValue.Value, newObject); if (!isSet) { result.Errors.Add($"Value of Property {propertyElement.Name} is not valid at Line {i}."); } } } }