internal XPathParser(string xpath, XmlNamespaceManager namespaces, IFunctionLibrary[] functionLibraries)
 {
     this.functionLibraries = functionLibraries;
     this.namespaces        = namespaces;
     this.lexer             = new XPathLexer(xpath);
     this.context           = namespaces as XsltContext;
 }
 private static string ParseXPathString(XPathLexer lexer, XmlNamespaceManager namespaceManager, bool throwOnFailure)
 {
     int firstTokenChar = lexer.FirstTokenChar;
     if (lexer.MoveNext())
     {
         XPathToken token = lexer.Token;
         StringBuilder builder = new StringBuilder(ParseXPathString(lexer, namespaceManager, throwOnFailure));
         if (XPathTokenID.NameTest == token.TokenID)
         {
             string prefix = token.Prefix;
             if (!string.IsNullOrEmpty(prefix))
             {
                 string str3 = namespaceManager.LookupNamespace(prefix);
                 if (!string.IsNullOrEmpty(str3))
                 {
                     builder = builder.Replace(prefix, str3, firstTokenChar, prefix.Length);
                 }
                 else if (throwOnFailure)
                 {
                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new IndexOutOfRangeException(System.ServiceModel.SR.GetString("ConfigXPathNamespacePrefixNotFound", new object[] { prefix })));
                 }
             }
         }
         return builder.ToString();
     }
     return lexer.ConsumedSubstring();
 }
        protected void ReadXPath(XmlReader reader, XmlNamespaceManager namespaces)
        {
            string xpath = reader.ReadString().Trim();

            if (xpath.Length != 0)
            {
                XPathLexer lexer = new XPathLexer(xpath, false);
                while (lexer.MoveNext())
                {
                    string prefix = lexer.Token.Prefix;
                    if (prefix.Length > 0)
                    {
                        string uri = null;
                        if (namespaces != null)
                        {
                            uri = namespaces.LookupNamespace(prefix);
                        }
                        if ((uri == null) || (uri.Length <= 0))
                        {
                            uri = reader.LookupNamespace(prefix);
                            if ((uri != null) && (uri.Length > 0))
                            {
                                if (namespaces == null)
                                {
                                    namespaces = new XPathMessageContext();
                                }
                                namespaces.AddNamespace(prefix, uri);
                            }
                        }
                    }
                }
            }
            this.Init(xpath, namespaces);
        }
 internal XPathParser(string xpath, XmlNamespaceManager namespaces, IFunctionLibrary[] functionLibraries)
 {
     this.functionLibraries = functionLibraries;
     this.namespaces = namespaces;
     this.lexer = new XPathLexer(xpath);
     this.context = namespaces as XsltContext;
 }
예제 #5
0
        /// <summary>
        /// Compile the given filter to run on an external (fx) xpath engine
        /// </summary>
        internal static OpcodeBlock CompileForExternalEngine(string expression, XmlNamespaceManager namespaces, object item, bool match)
        {
            // Compile...
            XPathExpression xpathExpr = QueryMatcher.fxCompiler.Compile(expression);

            // Fx will bind prefixes and functions here.
            if (namespaces != null)
            {
                // There's a bug in System.Xml.XPath.  If we pass an XsltContext to SetContext it won't throw if there's
                // an undefined prefix.
                if (namespaces is XsltContext)
                {
                    // Lex the xpath to find all prefixes used
                    XPathLexer lexer = new XPathLexer(expression, false);
                    while (lexer.MoveNext())
                    {
                        string prefix = lexer.Token.Prefix;

                        if (prefix.Length > 0 && namespaces.LookupNamespace(prefix) == null)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XsltException(SR.GetString(SR.FilterUndefinedPrefix, prefix)));
                        }
                    }
                }

                xpathExpr.SetContext(namespaces);
            }

            //
            // FORCE the function to COMPILE - they won't bind namespaces unless we check the return type
            //
            if (XPathResultType.Error == xpathExpr.ReturnType)
            {
                // This should never be reached.  The above property should throw if there's an error
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XPathException(SR.GetString(SR.FilterCouldNotCompile, expression)));
            }

            OpcodeBlock codeBlock = new OpcodeBlock();
            SingleFxEngineResultOpcode op;

            if (!match)
            {
                op = new QuerySingleFxEngineResultOpcode();
            }
            else
            {
                op = new MatchSingleFxEngineResultOpcode();
            }

            op.XPath = xpathExpr;
            op.Item  = item;

            codeBlock.Append(op);
            return(codeBlock);
        }
        protected void WriteXPath(XmlWriter writer, IXmlNamespaceResolver resolver)
        {
            int        startIndex     = 0;
            int        firstTokenChar = 0;
            string     text           = "";
            XPathLexer lexer          = new XPathLexer(this.xpath, false);
            Dictionary <string, string> dictionary = new Dictionary <string, string>();
            List <string> list = new List <string>();

            while (lexer.MoveNext())
            {
                string prefix = lexer.Token.Prefix;
                string str3   = resolver.LookupNamespace(prefix);
                if ((prefix.Length > 0) && ((str3 == null) || ((str3 != null) && (str3 != this.namespaces.LookupNamespace(prefix)))))
                {
                    if (this.xpath[firstTokenChar] == '$')
                    {
                        text       = text + this.xpath.Substring(startIndex, (firstTokenChar - startIndex) + 1);
                        startIndex = firstTokenChar + 1;
                    }
                    else
                    {
                        text       = text + this.xpath.Substring(startIndex, firstTokenChar - startIndex);
                        startIndex = firstTokenChar;
                    }
                    if (!dictionary.ContainsKey(prefix))
                    {
                        list.Add(prefix);
                        if (str3 != null)
                        {
                            string str4 = prefix;
                            for (int j = 0; (resolver.LookupNamespace(str4) != null) || (this.namespaces.LookupNamespace(str4) != null); j++)
                            {
                                str4 = str4 + j.ToString(NumberFormatInfo.InvariantInfo);
                            }
                            dictionary.Add(prefix, str4);
                        }
                        else
                        {
                            dictionary.Add(prefix, prefix);
                        }
                    }
                    text        = text + dictionary[prefix];
                    startIndex += prefix.Length;
                }
                firstTokenChar = lexer.FirstTokenChar;
            }
            text = text + this.xpath.Substring(startIndex);
            for (int i = 0; i < list.Count; i++)
            {
                string str5 = list[i];
                writer.WriteAttributeString("xmlns", dictionary[str5], null, this.namespaces.LookupNamespace(str5));
            }
            writer.WriteString(text);
        }
        protected void ReadXPath(XmlReader reader, XmlNamespaceManager namespaces)
        {
            // Pull in the string value
            // Trim should allow an all whitespace xpath to be perceived as a MatchAll.
            string xpath = reader.ReadString().Trim();

            // MatchAll XPathMessageFilter is allowed
            if (xpath.Length != 0)
            {
                // Lex the xpath to find all prefixes used
                XPathLexer lexer = new XPathLexer(xpath, false);

                while (lexer.MoveNext())
                {
                    string prefix = lexer.Token.Prefix;

                    if (prefix.Length > 0)
                    {
                        // Resolve the prefix. If the ns is not found, we'll let the Compiler throw the
                        // proper exception
                        string ns = null;

                        if (null != namespaces)
                        {
                            ns = namespaces.LookupNamespace(prefix);
                        }

                        if (null != ns && ns.Length > 0)
                        {
                            continue;
                        }

                        ns = reader.LookupNamespace(prefix);
                        if (null != ns && ns.Length > 0)
                        {
                            if (null == namespaces)
                            {
                                namespaces = new XPathMessageContext();
                            }

                            namespaces.AddNamespace(prefix, ns);
                        }
                    }
                }
            }

            this.Init(xpath, namespaces);
        }
        internal static OpcodeBlock CompileForExternalEngine(string expression, XmlNamespaceManager namespaces, object item, bool match)
        {
            SingleFxEngineResultOpcode opcode;
            XPathExpression            expression2 = fxCompiler.Compile(expression);

            if (namespaces != null)
            {
                if (namespaces is XsltContext)
                {
                    XPathLexer lexer = new XPathLexer(expression, false);
                    while (lexer.MoveNext())
                    {
                        string prefix = lexer.Token.Prefix;
                        if ((prefix.Length > 0) && (namespaces.LookupNamespace(prefix) == null))
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XsltException(System.ServiceModel.SR.GetString("FilterUndefinedPrefix", new object[] { prefix })));
                        }
                    }
                }
                expression2.SetContext(namespaces);
            }
            if (XPathResultType.Error == expression2.ReturnType)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XPathException(System.ServiceModel.SR.GetString("FilterCouldNotCompile", new object[] { expression })));
            }
            OpcodeBlock block = new OpcodeBlock();

            if (!match)
            {
                opcode = new QuerySingleFxEngineResultOpcode();
            }
            else
            {
                opcode = new MatchSingleFxEngineResultOpcode();
            }
            opcode.XPath = expression2;
            opcode.Item  = item;
            block.Append(opcode);
            return(block);
        }
        static string ParseXPathString(XPathLexer lexer, XmlNamespaceManager namespaceManager, bool throwOnFailure)
        {
            string retVal = String.Empty;

            int currentTokenStart = lexer.FirstTokenChar;
            if (lexer.MoveNext())
            {
                XPathToken token = lexer.Token;
                StringBuilder xPathString = new StringBuilder(XPathMessageFilterElementComparer.ParseXPathString(lexer, namespaceManager, throwOnFailure));

                if (XPathTokenID.NameTest == token.TokenID)
                {
                    string nsPrefix = token.Prefix;
                    if (!String.IsNullOrEmpty(nsPrefix))
                    {
                        string ns = namespaceManager.LookupNamespace(nsPrefix);
                        if (!String.IsNullOrEmpty(ns))
                        {
                            xPathString = xPathString.Replace(nsPrefix, ns, currentTokenStart, nsPrefix.Length);
                        }
                        else
                        {
                            if (throwOnFailure)
                            {
                                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new IndexOutOfRangeException(SR.GetString(SR.ConfigXPathNamespacePrefixNotFound, nsPrefix)));
                            }
                        }
                    }
                }

                retVal = xPathString.ToString();
            }
            else
            {
                retVal = lexer.ConsumedSubstring();
            }

            return retVal;
        }
 internal static string ParseXPathString(XPathMessageFilter filter, bool throwOnFailure)
 {
     XPathLexer lexer = new XPathLexer(filter.XPath);
     return XPathMessageFilterElementComparer.ParseXPathString(lexer, filter.Namespaces, throwOnFailure);
 }
        protected void WriteXPath(XmlWriter writer, IXmlNamespaceResolver resolver)
        {
            // Lex the xpath to find all prefixes used
            int        startChar = 0;
            int        tmp       = 0;
            string     newXPath  = "";
            XPathLexer lexer     = new XPathLexer(xpath, false);
            Dictionary <string, string> prefixMap = new Dictionary <string, string>();
            List <string> prefixes = new List <string>();

            while (lexer.MoveNext())
            {
                string nsPrefix = lexer.Token.Prefix;
                string nsNS     = resolver.LookupNamespace(nsPrefix);

                // Check if we need to write the namespace
                if (nsPrefix.Length > 0 && (nsNS == null || (nsNS != null && nsNS != this.namespaces.LookupNamespace(nsPrefix))))
                {
                    // Write the previous xpath segment
                    if (this.xpath[tmp] == '$')
                    {
                        newXPath += this.xpath.Substring(startChar, tmp - startChar + 1);
                        startChar = tmp + 1;
                    }
                    else
                    {
                        newXPath += this.xpath.Substring(startChar, tmp - startChar);
                        startChar = tmp;
                    }

                    // Check if we need a new prefix
                    if (!prefixMap.ContainsKey(nsPrefix))
                    {
                        prefixes.Add(nsPrefix);
                        if (nsNS != null)
                        {
                            string newPrefix = nsPrefix;
                            int    i         = 0;
                            while (resolver.LookupNamespace(newPrefix) != null || this.namespaces.LookupNamespace(newPrefix) != null)
                            {
                                newPrefix = newPrefix + i.ToString(NumberFormatInfo.InvariantInfo);
                                ++i;
                            }
                            prefixMap.Add(nsPrefix, newPrefix);
                        }
                        else
                        {
                            prefixMap.Add(nsPrefix, nsPrefix);
                        }
                    }

                    // Write the new prefix
                    newXPath += prefixMap[nsPrefix];

                    // Update the xpath marker
                    startChar += nsPrefix.Length;
                }
                tmp = lexer.FirstTokenChar;
            }
            newXPath += this.xpath.Substring(startChar);    // Consume the remainder of the xpath

            // Write the namespaces
            for (int i = 0; i < prefixes.Count; ++i)
            {
                string prefix = prefixes[i];
                writer.WriteAttributeString("xmlns", prefixMap[prefix], null, this.namespaces.LookupNamespace(prefix));
            }

            // Write the XPath
            writer.WriteString(newXPath);
        }