Ejemplo n.º 1
0
        /// <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));
        }
Ejemplo n.º 2
0
        /// <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);
        }