private IEnumerable <IDiagnostic> MatchMinMaxOccurs([NotNull] Item item, [NotNull] ITextNode schemaTextNode, [NotNull, ItemNotNull] ITextNode[] schemaChildNodes, [NotNull, ItemNotNull] Item[] children) { foreach (var schemaChildNode in schemaChildNodes) { if (schemaChildNode.Key != "item") { throw new InvalidOperationException($"Unexpected node {schemaChildNode.Key} at {schemaChildNode.Snapshot.SourceFile.AbsoluteFileName} {schemaChildNode.TextSpan}"); } // in references, the referring text node may overwrite the referred text nodes var minOccurs = 0; var maxOccurs = 0; if (schemaChildNode.HasAttribute("minOccurs")) { minOccurs = int.Parse(schemaChildNode.GetAttributeValue("minOccurs", "0")); } if (schemaTextNode.HasAttribute("minOccurs")) { minOccurs = int.Parse(schemaTextNode.GetAttributeValue("minOccurs", "0")); } if (schemaChildNode.HasAttribute("maxOccurs")) { maxOccurs = int.Parse(schemaChildNode.GetAttributeValue("maxOccurs", "0")); } if (schemaTextNode.HasAttribute("maxOccurs")) { maxOccurs = int.Parse(schemaTextNode.GetAttributeValue("maxOccurs", "0")); } if (minOccurs <= 0 && maxOccurs <= 0) { continue; } var count = children.Count(child => IsMatch(child, schemaChildNode)); if (minOccurs > 0 && count < minOccurs) { yield return(Factory.Diagnostic(Msg.D1025, item.Snapshot.SourceFile.RelativeFileName, TraceHelper.GetTextNode(item).TextSpan, Severity.Error, $"Item {GetText(schemaChildNode)} must occur at least {minOccurs} times [ArchitectureSchema]")); } if (maxOccurs > 0 && count > maxOccurs) { yield return(Factory.Diagnostic(Msg.D1025, item.Snapshot.SourceFile.RelativeFileName, TraceHelper.GetTextNode(item).TextSpan, Severity.Error, $"Item {GetText(schemaChildNode)} must not occur more than {maxOccurs} times [ArchitectureSchema]")); } } }
public static bool GetAttributeBool([NotNull] this ITextNode textNode, [NotNull] string attributeName, bool defaultValue = false) { if (!textNode.HasAttribute(attributeName)) { return(defaultValue); } var value = textNode.GetAttributeValue(attributeName); return(string.Equals(value, "true", StringComparison.OrdinalIgnoreCase)); }