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); }
/// <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); }