/// <summary> /// Returns a parsed version of the XPath query by its name. The parsed query does not contain any macros, all macros will be expanded to their respective sequences. /// </summary> /// <param name="name">The unique name under which the XPath query is registered in the XPath library.</param> /// <returns>The parsed version of the XPath query.</returns> public string GetXPathQuery(string name) { Guard.ArgumentNotNullOrEmptyString(name, "name"); XPathQueryInfo queryInfo = this.Queries.Get(name); if (null == queryInfo || String.IsNullOrEmpty(queryInfo.XPath)) { throw new ConfigurationErrorsException(String.Format(CultureInfo.InvariantCulture, ExceptionMessages.XPathQueryNotDefined, name)); } return(queryInfo.ParseQuery(this)); }
/// <summary> /// Parses the current XPath query in order to expand the prefixed elements with their fully qualified references. /// </summary> internal string ParseQuery(XPathQueryLibrary xPathLib) { if (null == this.parsedQueryText || !this.parsed) { lock (lockObject) { if (null == this.parsedQueryText || !this.parsed) { string currentXPath = (string)base[XPathQueryProperty]; // Check whether or not the XPath Query Library object has any namespace definitions if (xPathLib.Namespaces.Count > 0) { // Retrieve the list of namespaces along with their defined prefixes XmlNamespaceManager namespaceManager = xPathLib.Namespaces.NamespaceManager; // Represents the method that is called each time a regular expression match is found during a Replace method operation. MatchEvaluator evaluator = new MatchEvaluator(match => { string resolvedNamespace = namespaceManager.LookupNamespace(match.Groups[Resources.NamespaceGroupName].Value); if (resolvedNamespace != null) { // If the XML namespace was found, return a localized version of the XPath query (e.g. *[local-name()='NodeName' and namespace-uri()='FoundNamespace']) return(String.Format(CultureInfo.InvariantCulture, Resources.XPathQueryTargetElementRef, match.Groups[Resources.NodeNameGroupName].Value, resolvedNamespace)); } else { // If the target XML namespace is not found, simply return the original fully qualified node name. return(match.Groups[Resources.FullyQualifiedNodeNameGroupName].Value); } }); // Replace the XPath query with its parsed version. currentXPath = nsExpansionExpr.Replace(currentXPath, evaluator); } // Perform macro substitution only if at least 1 macro has been found. if (currentXPath != null && currentXPath.Contains("{$")) { // Represents the method that is called each time a regular expression match is found during a Replace method operation. MatchEvaluator evaluator = new MatchEvaluator(match => { XPathQueryInfo refQueryInfo = xPathLib.Queries.Get(match.Groups[1].Value); // Check if we found the referenced XPathQueryInfo, also make sure we don't end up with a circular reference. if (refQueryInfo != null && String.Compare(refQueryInfo.Name, this.Name, false, CultureInfo.InvariantCulture) != 0) { return(refQueryInfo.ParseQuery(xPathLib)); } else { return(null); } }); // Update the XPath query with its parsed version. currentXPath = macroSearchExpr.Replace(currentXPath, evaluator); } this.parsedQueryText = currentXPath; this.parsed = true; } } } return(this.parsedQueryText); }