/// <summary> /// The parse. /// </summary> /// <param name="itemText"> /// The text to parse and replace any replacement values in /// </param> /// <param name="replacementValues"> /// The replacement values. /// </param> /// <param name="itemDictionary"> /// The parent item dictionary that will be used for include statements /// </param> /// <returns> /// The <see cref="string" />. /// </returns> public static string Parse( string itemText, IDictionary <string, object> replacementValues, BaseItemDictionary itemDictionary) { return(ProcessReplacementValues( ProcessIncludeStatements(ProcessReplacementValues(itemText, replacementValues), itemDictionary), replacementValues)); }
/// <summary> /// The process include statements. /// </summary> /// <param name="libraryItemText"> /// The library item text. /// </param> /// <param name="itemDictionary"> /// The item dictionary. /// </param> /// <returns> /// The <see cref="string" />. /// </returns> private static string ProcessIncludeStatements(string libraryItemText, BaseItemDictionary itemDictionary) { const string IncludeStatementPattern = @" INCLUDE \s+ ([A-Za-z0-9_\.]+) (?# The name of the item from the Test Data Library. Can contain alpha-numeric characters, underscores, and periods.) \s* ( (?# Can have a comma followed by JSON-style objects to specify params) ,\s* \[? (?# JSON-style array brackets are optional when specifying multiple JSON-style objects) ( (?# This group matches zero, one, or more JSON-style objects) \s* \{ ( " + JsonStylePropertyPattern + @" )+ \},? \s* )* \]? )? "; var includeStatementRegex = new Regex( IncludeStatementPattern, RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase); return(includeStatementRegex.Replace( libraryItemText, includeStatementMatch => { var includedLibraryItemName = includeStatementMatch.Groups[1].Value; string includeLibraryItem; try { includeLibraryItem = itemDictionary[includedLibraryItemName].LibraryItemText; } catch (KeyNotFoundException keyNotFoundEx) { throw new InvalidOperationException( $"The library item \"{includedLibraryItemName}\" that is part of an include statement was not found.\n\n{libraryItemText}", keyNotFoundEx); } string newIncludeLibraryItem; // Are there any JSON-style replacement values specified? if (includeStatementMatch.Groups[3].Captures.Count > 0) { // JSON-style replacement values were specified. If more than one was specified, // then each one is like a separate include statement. var allIncludes = new StringBuilder(); foreach (Capture capture in includeStatementMatch.Groups[3].Captures) { allIncludes.AppendLine( ProcessReplacementValues( includeLibraryItem, GetReplacementValuesFromJsonString(capture.Value))); } newIncludeLibraryItem = allIncludes.ToString(); } else { // Just a plain INCLUDE statement with no JSON-style replacement values. E.g.: INCLUDE Some.Stuff newIncludeLibraryItem = ProcessReplacementValues(includeLibraryItem, null); } // Recursively process all include statements return ProcessIncludeStatements(newIncludeLibraryItem, itemDictionary); })); }