public static PathOptimizer <string> ForXPaths(XElement xml, string xpath, XPathPartGenerator[] nodeReplacers, XPathScoreRule[] scoreRules, int desiredCount) { int i = 0; int len = XPathFinder.Split(xpath).Length; int timesFindAllShortenedPathsCalled = 0; return(new PathOptimizer <string>( nextNodesGetter: (p) => { if (i < len) { var results = XPathFinder.FindXpathsWithReplacedNode(XPathFinder.Split(p), i, xml, nodeReplacers); return results.Select(r => XPathFinder.Merge(r)); } else { var results = XPathFinder.FindAllShortenedPaths(p, xml); return results; } }, scoreMeasurer: (p) => XPathScorer.GetScore(p, scoreRules), onIterationFinished: () => { if (i < len) { i++; } else { timesFindAllShortenedPathsCalled++; } }, checkFinished: () => timesFindAllShortenedPathsCalled >= desiredCount)); }
private static void OptimizePaths(XElement xml, IEnumerable <string> paths, int count, string[] attributes, bool measureSpeed) { IEnumerable <XPathPartGenerator> pathGenerators = new[] { XPathPartGenerator.TagOnly() } .Concat(attributes.Select(a => XPathPartGenerator.TagWithAttribute(a))) .ToArray(); IEnumerable <XPathScoreRule> scoreRules = new[] { XPathScoreRule.PeneltizeStar(), XPathScoreRule.PeneltizeIndex(scoreWeight: 2), XPathScoreRule.PeneltizeStarWithIndex(), XPathScoreRule.TagUniqueness(xml), XPathScoreRule.PeneltizeLackOfAttributes(scoreWeight: 1), XPathScoreRule.AttributeUniqueness(xml, scoreWeight: 1) }; if (measureSpeed) { scoreRules = scoreRules.Concat(new[] { XPathScoreRule.MeasureTime(xml) }); } var tasks = paths .ToDictionary(p => p, p => Task.Run(() => { var path = XPathFinder.FindSimplestXPath(p, xml); scoreRules = scoreRules.Concat(new[] { XPathScoreRule.PeneltizeLength(path.Split('/').Length, 0.1, 0.4, scoreWeight: 2) }); return(DoOptiize(xml, path, count, pathGenerators.ToArray(), scoreRules.ToArray())); })); foreach (var task in tasks) { Console.WriteLine("Results for : " + task.Key + Environment.NewLine); foreach (var line in task.Value.Result) { Console.WriteLine(line); } Console.WriteLine(); } }