/* * LocationPath ::= RelativeLocationPath | '/' RelativeLocationPath? | '//' RelativeLocationPath */ private Node ParseLocationPath() { if (scanner.Kind == LexKind.Slash) { scanner.NextLex(); Node opnd = builder.Axis(XPathAxis.Root, XPathNodeType.All, null, null); if (IsStep(scanner.Kind)) { opnd = builder.JoinStep(opnd, ParseRelativeLocationPath()); } return(opnd); } else if (scanner.Kind == LexKind.SlashSlash) { scanner.NextLex(); return(builder.JoinStep( builder.Axis(XPathAxis.Root, XPathNodeType.All, null, null), builder.JoinStep( builder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), ParseRelativeLocationPath() ) )); } else { return(ParseRelativeLocationPath()); } }
internal static void InternalParseNodeTest(XPathScanner scanner, XPathAxis axis, out XPathNodeType nodeType, out string nodePrefix, out string nodeName) { switch (scanner.Kind) { case LexKind.Name: if (scanner.CanBeFunction && IsNodeType(scanner)) { nodePrefix = null; nodeName = null; switch (scanner.Name) { case "comment": nodeType = XPathNodeType.Comment; break; case "text": nodeType = XPathNodeType.Text; break; case "node": nodeType = XPathNodeType.All; break; default: Debug.Assert(scanner.Name == "processing-instruction"); nodeType = XPathNodeType.ProcessingInstruction; break; } scanner.NextLex(); scanner.PassToken(LexKind.LParens); if (nodeType == XPathNodeType.ProcessingInstruction) { if (scanner.Kind != LexKind.RParens) // 'processing-instruction' '(' Literal ')' { scanner.CheckToken(LexKind.String); // It is not needed to set nodePrefix here, but for our current implementation // comparing whole QNames is faster than comparing just local names nodePrefix = string.Empty; nodeName = scanner.StringValue; scanner.NextLex(); } } scanner.PassToken(LexKind.RParens); } else { nodePrefix = scanner.Prefix; nodeName = scanner.Name; nodeType = PrincipalNodeType(axis); scanner.NextLex(); if (nodeName == "*") { nodeName = null; } } break; case LexKind.Star: nodePrefix = null; nodeName = null; nodeType = PrincipalNodeType(axis); scanner.NextLex(); break; default: throw scanner.CreateException(Res.XPath_NodeTestExpected, scanner.RawValue); } }