using System.Xml.XPath; namespace Umbraco.Core.Xml { /// /// Provides extensions to XPathNavigator. /// internal static class XPathNavigatorExtensions { /// /// Selects a node set, using the specified XPath expression. /// /// A source XPathNavigator. /// An XPath expression. /// A set of XPathVariables. /// An iterator over the nodes matching the specified expression. public static XPathNodeIterator Select(this XPathNavigator navigator, string expression, params XPathVariable[] variables) { if (variables == null || variables.Length == 0 || variables[0] == null) return navigator.Select(expression); // Reflector shows that the standard XPathNavigator.Compile method just does // return XPathExpression.Compile(xpath); // only difference is, XPathNavigator.Compile is virtual so it could be overriden // by a class inheriting from XPathNavigator... there does not seem to be any // doing it in the Framework, though... so we'll assume it's much cleaner to use // the static compile: var compiled = XPathExpression.Compile(expression); var context = new DynamicContext(); foreach (var variable in variables) context.AddVariable(variable.Name, variable.Value); compiled.SetContext(context); return navigator.Select(compiled); } /// /// Selects a node set, using the specified XPath expression. /// /// A source XPathNavigator. /// An XPath expression. /// A set of XPathVariables. /// An iterator over the nodes matching the specified expression. public static XPathNodeIterator Select(this XPathNavigator navigator, XPathExpression expression, params XPathVariable[] variables) { if (variables == null || variables.Length == 0 || variables[0] == null) return navigator.Select(expression); var compiled = expression.Clone(); // clone for thread-safety var context = new DynamicContext(); foreach (var variable in variables) context.AddVariable(variable.Name, variable.Value); compiled.SetContext(context); return navigator.Select(compiled); } } }