private Node ParseRelativeLocationPath() { if (++parseRelativePath > MaxParseRelativePathDepth) { if (System.Xml.XmlConfiguration.XsltConfigSection.LimitXPathComplexity) { throw scanner.CreateException(System.Xml.Utils.Res.Xslt_InputTooComplex); } } Node opnd = ParseStep(); if (scanner.Kind == LexKind.Slash) { scanner.NextLex(); opnd = builder.JoinStep(opnd, ParseRelativeLocationPath()); } else if (scanner.Kind == LexKind.SlashSlash) { scanner.NextLex(); opnd = builder.JoinStep(opnd, builder.JoinStep( builder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), ParseRelativeLocationPath() ) ); } --parseRelativePath; return(opnd); }
private Node ParseRelativeLocationPath() { if (++_parseRelativePath > MaxParseRelativePathDepth) { if (LocalAppContextSwitches.LimitXPathComplexity) { throw _scanner.CreateException(SR.Xslt_InputTooComplex); } } Node opnd = ParseStep(); if (_scanner.Kind == LexKind.Slash) { _scanner.NextLex(); opnd = _builder.JoinStep(opnd, ParseRelativeLocationPath()); } else if (_scanner.Kind == LexKind.SlashSlash) { _scanner.NextLex(); opnd = _builder.JoinStep(opnd, _builder.JoinStep( _builder.Axis(XPathAxis.DescendantOrSelf, XPathNodeType.All, null, null), ParseRelativeLocationPath() ) ); } --_parseRelativePath; return(opnd); }
/* * Step ::= '.' | '..' | (AxisName '::' | '@')? NodeTest Predicate* */ private Node ParseStep() { Node opnd; if (LexKind.Dot == scanner.Kind) //>> '.' { scanner.NextLex(); opnd = builder.Axis(XPathAxis.Self, XPathNodeType.All, null, null); if (LexKind.LBracket == scanner.Kind) { throw scanner.CreateException(Res.XPath_PredicateAfterDot); } } else if (LexKind.DotDot == scanner.Kind) //>> '..' { scanner.NextLex(); opnd = builder.Axis(XPathAxis.Parent, XPathNodeType.All, null, null); if (LexKind.LBracket == scanner.Kind) { throw scanner.CreateException(Res.XPath_PredicateAfterDotDot); } } else //>> (AxisName '::' | '@')? NodeTest Predicate* { XPathAxis axis; switch (scanner.Kind) { case LexKind.Axis: //>> AxisName '::' axis = GetAxis(scanner.Name, scanner); scanner.NextLex(); break; case LexKind.At: //>> '@' axis = XPathAxis.Attribute; scanner.NextLex(); break; case LexKind.Name: case LexKind.Star: // NodeTest must start with Name or '*' axis = XPathAxis.Child; break; default: throw scanner.CreateException(Res.XPath_UnexpectedToken, scanner.RawValue); } opnd = ParseNodeTest(axis); while (LexKind.LBracket == scanner.Kind) { opnd = builder.Predicate(opnd, ParsePredicate(), IsReverseAxis(axis)); } } return(opnd); }
internal static XPathAxis GetAxis(string axisName, XPathScanner scanner) { switch (axisName) { case "ancestor": return(XPathAxis.Ancestor); case "ancestor-or-self": return(XPathAxis.AncestorOrSelf); case "attribute": return(XPathAxis.Attribute); case "child": return(XPathAxis.Child); case "descendant": return(XPathAxis.Descendant); case "descendant-or-self": return(XPathAxis.DescendantOrSelf); case "following": return(XPathAxis.Following); case "following-sibling": return(XPathAxis.FollowingSibling); case "namespace": return(XPathAxis.Namespace); case "parent": return(XPathAxis.Parent); case "preceding": return(XPathAxis.Preceding); case "preceding-sibling": return(XPathAxis.PrecedingSibling); case "self": return(XPathAxis.Self); default: throw scanner.CreateException(Res.XPath_UnknownAxis, axisName); } }
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); } }