NumberPattern FindPattern(decimal value, NumberLength?nl = null) { if (!nl.HasValue) { nl = Options.Length; } value = Math.Abs(value); // Determine the format length type. var flt = nl == NumberLength.Default ? "[not(@type)]" : $"[@type='{nl.ToString().ToLowerInvariant()}']"; // Determine the path in the ldml to the pattern(s) var path = String.Empty; if (Options.Style == NumberStyle.Decimal) { path = $"ldml/numbers/decimalFormats[@numberSystem='{NumberingSystem.Id}']/decimalFormatLength{flt}/decimalFormat"; } else if (Options.Style == NumberStyle.Percent) { path = $"ldml/numbers/percentFormats[@numberSystem='{NumberingSystem.Id}']/percentFormatLength{flt}/percentFormat"; } else if (Options.Style == NumberStyle.Scientific) { path = $"ldml/numbers/scientificFormats[@numberSystem='{NumberingSystem.Id}']/scientificFormatLength{flt}/scientificFormat"; } else if (Options.Style == NumberStyle.CurrencyStandard) { path = $"ldml/numbers/currencyFormats[@numberSystem='{NumberingSystem.Id}']/currencyFormatLength{flt}/currencyFormat[@type='standard']"; } else if (Options.Style == NumberStyle.CurrencyAccounting) { path = $"ldml/numbers/currencyFormats[@numberSystem='{NumberingSystem.Id}']/currencyFormatLength{flt}/currencyFormat[@type='accounting']"; } else { throw new NotImplementedException($"Unknown NumberStyle '{Options.Style}'."); } var xml = Locale.FindOrDefault(path); // Fall back to default number length; if (xml == null && nl != NumberLength.Default) { return(FindPattern(value, NumberLength.Default)); } // Should not happen. if (xml == null) { throw new KeyNotFoundException($"Cannot find CLDR '{path}'."); } // Get the best pattern. var category = Plural.Create(Locale).Category(value); NumberPattern best = null; NumberPattern previous = null; var pattern = xml.SelectChildren("pattern", ""); while (pattern.MoveNext()) { var p = NumberPattern.Parse(pattern.Current); // If not a value range, then this is the best pattern. if (!p.MinValue.HasValue) { best = p; break; } // Only consider a pattern with the correct count. if (p.Count != category) { continue; } // Get closest value in the range. if (p.MinValue.Value > value) { best = previous; break; } previous = p; } best = best ?? previous ?? new NumberPattern { FormatString = "0" }; return(best); }