Example #1
0
 protected string AppendStep(string basePath, XPathAxis stepAxis, string stepNodeTest, string predicate) {
     return String.Concat(
         EnsureTrailingSlash(basePath), 
         GetAxisString(stepAxis), 
         stepNodeTest, 
         EnsureBracketedPredicate(predicate));
 }
Example #2
0
        public void NextLex()
        {
            prevLexEnd = curIndex;
            prevKind = kind;
            SkipSpace();
            lexStart = curIndex;

            switch (curChar) {
            case '\0':
                kind = LexKind.Eof;
                return;
            case '(': case ')': case '[': case ']':
            case '@': case ',': case '$': case '}':
                kind = (LexKind)curChar;
                NextChar();
                break;
            case '.':
                NextChar();
                if (curChar == '.') {
                    kind = LexKind.DotDot;
                    NextChar();
                } else if (IsAsciiDigit(curChar)) {
                    SetSourceIndex(lexStart);
                    goto case '0';
                } else {
                    kind = LexKind.Dot;
                }
                break;
            case ':':
                NextChar();
                if (curChar == ':') {
                    kind = LexKind.ColonColon;
                    NextChar();
                } else {
                    kind = LexKind.Unknown;
                }
                break;
            case '*':
                kind = LexKind.Star;
                NextChar();
                CheckOperator(true);
                break;
            case '/':
                NextChar();
                if (curChar == '/') {
                    kind = LexKind.SlashSlash;
                    NextChar();
                } else {
                    kind = LexKind.Slash;
                }
                break;
            case '|':
                kind = LexKind.Union;
                NextChar();
                break;
            case '+':
                kind = LexKind.Plus;
                NextChar();
                break;
            case '-':
                kind = LexKind.Minus;
                NextChar();
                break;
            case '=':
                kind = LexKind.Eq;
                NextChar();
                break;
            case '!':
                NextChar();
                if (curChar == '=') {
                    kind = LexKind.Ne;
                    NextChar();
                } else {
                    kind = LexKind.Unknown;
                }
                break;
            case '<':
                NextChar();
                if (curChar == '=') {
                    kind = LexKind.Le;
                    NextChar();
                } else {
                    kind = LexKind.Lt;
                }
                break;
            case '>':
                NextChar();
                if (curChar == '=') {
                    kind = LexKind.Ge;
                    NextChar();
                } else {
                    kind = LexKind.Gt;
                }
                break;
            case '"':
            case '\'':
                kind = LexKind.String;
                ScanString();
                break;
            case '0': case '1': case '2': case '3':
            case '4': case '5': case '6': case '7':
            case '8': case '9':
                kind = LexKind.Number;
                ScanNumber();
                break;
            default:
                this.name = ScanNCName();
                if (this.name != null) {
                    kind = LexKind.Name;
                    this.prefix = string.Empty;
                    this.canBeFunction = false;
                    this.axis = XPathAxis.Unknown;
                    bool colonColon = false;
                    int saveSourceIndex = curIndex;

                    // "foo:bar" or "foo:*" -- one lexeme (no spaces allowed)
                    // "foo::" or "foo ::"  -- two lexemes, reported as one (AxisName)
                    // "foo:?" or "foo :?"  -- lexeme "foo" reported
                    if (curChar == ':') {
                        NextChar();
                        if (curChar == ':') {   // "foo::" -> OperatorName, AxisName
                            NextChar();
                            colonColon = true;
                            SetSourceIndex(saveSourceIndex);
                        } else {                // "foo:bar", "foo:*" or "foo:?"
                            if (curChar == '*')
                            {
                                NextChar();
                                this.prefix = this.name;
                                this.name = "*";
                            }
                            else
                            {
                                string ncName = ScanNCName();
                                if (ncName != null)
                                {
                                    this.prefix = this.name;
                                    this.name = ncName;
                                    // Look ahead for '(' to determine whether QName can be a FunctionName
                                    saveSourceIndex = curIndex;
                                    SkipSpace();
                                    this.canBeFunction = (curChar == '(');
                                    SetSourceIndex(saveSourceIndex);
                                }
                                else
                                {
                                    // "foo:?" -> OperatorName, NameTest
                                    // Return "foo" and leave ":" to be reported later as an unknown lexeme
                                    SetSourceIndex(saveSourceIndex);
                                }
                            }
                        }
                    } else {
                        SkipSpace();
                        if (curChar == ':') {   // "foo ::" or "foo :?"
                            NextChar();
                            if (curChar == ':') {
                                NextChar();
                                colonColon = true;
                            }
                            SetSourceIndex(saveSourceIndex);
                        } else {
                            this.canBeFunction = (curChar == '(');
                        }
                    }
                    if (!CheckOperator(false) && colonColon) {
                        this.axis = CheckAxis();
                    }
                } else {
                    kind = LexKind.Unknown;
                    NextChar();
                }
                break;
            }
        }
Example #3
0
 protected string AppendStep(string basePath, XPathAxis stepAxis, string stepNodeTest) {
     return AppendStep(basePath, stepAxis, stepNodeTest, String.Empty);
 }
Example #4
0
 private string GetAxisString(XPathAxis stepAxis)
 {
     switch (stepAxis)
     {
         case XPathAxis.Child:
             return string.Empty;
         case XPathAxis.Descendant:
             return "descendant::";
         case XPathAxis.Parent:
             return "parent::";
         case XPathAxis.Ancestor:
             return "ancestor::";
         case XPathAxis.FollowingSibling:
             return "following-sibling::";
         case XPathAxis.PrecedingSibling:
             return "preceding-sibling::";
         case XPathAxis.Following:
             return "following::";
         case XPathAxis.Preceding:
             return "preceding::";
         case XPathAxis.Self:
             return "self::";
         case XPathAxis.DescendantOrSelf:
             return "/";
         case XPathAxis.AncestorOrSelf:
             return "ancestor-or-self::";
         default:
             return string.Empty;
     }
 }
Example #5
0
 private string GetAxisString(XPathAxis stepAxis) {
     switch (stepAxis) {
         case XPathAxis.Child:
             return String.Empty;
         case XPathAxis.Descendant:
             return "descendant::";
         case XPathAxis.Parent:
             return "parent::";
         case XPathAxis.Ancestor:
             return "ancestor::";
         case XPathAxis.FollowingSibling:
             return "following-sibling::";
         case XPathAxis.PrecedingSibling:
             return "preceding-sibling::";
         case XPathAxis.Following:
             return "following::";
         case XPathAxis.Preceding:
             return "preceding::";
         case XPathAxis.Self:
             return "self::";
         case XPathAxis.DescendantOrSelf:
             return "/";
         case XPathAxis.AncestorOrSelf:
             return "ancestor-or-self::";
         default:
             Debug.Fail("There should be no XPathAxis enum value that isn't handled in this switch statement");
             return String.Empty;
     }
 }
Example #6
0
        public void NextLex()
        {
            _prevLexEnd = _curIndex;
            _prevKind = _kind;
            SkipSpace();
            _lexStart = _curIndex;

            switch (_curChar)
            {
                case '\0':
                    _kind = LexKind.Eof;
                    return;
                case '(':
                case ')':
                case '[':
                case ']':
                case '@':
                case ',':
                case '$':
                case '}':
                    _kind = (LexKind)_curChar;
                    NextChar();
                    break;
                case '.':
                    NextChar();
                    if (_curChar == '.')
                    {
                        _kind = LexKind.DotDot;
                        NextChar();
                    }
                    else if (IsAsciiDigit(_curChar))
                    {
                        SetSourceIndex(_lexStart);
                        goto case '0';
                    }
                    else
                    {
                        _kind = LexKind.Dot;
                    }
                    break;
                case ':':
                    NextChar();
                    if (_curChar == ':')
                    {
                        _kind = LexKind.ColonColon;
                        NextChar();
                    }
                    else
                    {
                        _kind = LexKind.Unknown;
                    }
                    break;
                case '*':
                    _kind = LexKind.Star;
                    NextChar();
                    CheckOperator(true);
                    break;
                case '/':
                    NextChar();
                    if (_curChar == '/')
                    {
                        _kind = LexKind.SlashSlash;
                        NextChar();
                    }
                    else
                    {
                        _kind = LexKind.Slash;
                    }
                    break;
                case '|':
                    _kind = LexKind.Union;
                    NextChar();
                    break;
                case '+':
                    _kind = LexKind.Plus;
                    NextChar();
                    break;
                case '-':
                    _kind = LexKind.Minus;
                    NextChar();
                    break;
                case '=':
                    _kind = LexKind.Eq;
                    NextChar();
                    break;
                case '!':
                    NextChar();
                    if (_curChar == '=')
                    {
                        _kind = LexKind.Ne;
                        NextChar();
                    }
                    else
                    {
                        _kind = LexKind.Unknown;
                    }
                    break;
                case '<':
                    NextChar();
                    if (_curChar == '=')
                    {
                        _kind = LexKind.Le;
                        NextChar();
                    }
                    else
                    {
                        _kind = LexKind.Lt;
                    }
                    break;
                case '>':
                    NextChar();
                    if (_curChar == '=')
                    {
                        _kind = LexKind.Ge;
                        NextChar();
                    }
                    else
                    {
                        _kind = LexKind.Gt;
                    }
                    break;
                case '"':
                case '\'':
                    _kind = LexKind.String;
                    ScanString();
                    break;
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    _kind = LexKind.Number;
                    ScanNumber();
                    break;
                default:
                    if (_xmlCharType.IsStartNCNameSingleChar(_curChar)
#if XML10_FIFTH_EDITION
                        || xmlCharType.IsNCNameHighSurrogateChar(curChar)
#endif
                        )
                    {
                        _kind = LexKind.Name;
                        _name = ScanNCName();
                        _prefix = string.Empty;
                        _canBeFunction = false;
                        _axis = XPathAxis.Unknown;
                        bool colonColon = false;
                        int saveSourceIndex = _curIndex;

                        // "foo:bar" or "foo:*" -- one lexeme (no spaces allowed)
                        // "foo::" or "foo ::"  -- two lexemes, reported as one (AxisName)
                        // "foo:?" or "foo :?"  -- lexeme "foo" reported
                        if (_curChar == ':')
                        {
                            NextChar();
                            if (_curChar == ':')
                            {   // "foo::" -> OperatorName, AxisName
                                NextChar();
                                colonColon = true;
                                SetSourceIndex(saveSourceIndex);
                            }
                            else
                            {                // "foo:bar", "foo:*" or "foo:?"
                                if (_curChar == '*')
                                {
                                    NextChar();
                                    _prefix = _name;
                                    _name = "*";
                                }
                                else if (_xmlCharType.IsStartNCNameSingleChar(_curChar)
#if XML10_FIFTH_EDITION
                                    || xmlCharType.IsNCNameHighSurrogateChar(curChar)
#endif
                                    )
                                {
                                    _prefix = _name;
                                    _name = ScanNCName();
                                    // Look ahead for '(' to determine whether QName can be a FunctionName
                                    saveSourceIndex = _curIndex;
                                    SkipSpace();
                                    _canBeFunction = (_curChar == '(');
                                    SetSourceIndex(saveSourceIndex);
                                }
                                else
                                {            // "foo:?" -> OperatorName, NameTest
                                    // Return "foo" and leave ":" to be reported later as an unknown lexeme
                                    SetSourceIndex(saveSourceIndex);
                                }
                            }
                        }
                        else
                        {
                            SkipSpace();
                            if (_curChar == ':')
                            {   // "foo ::" or "foo :?"
                                NextChar();
                                if (_curChar == ':')
                                {
                                    NextChar();
                                    colonColon = true;
                                }
                                SetSourceIndex(saveSourceIndex);
                            }
                            else
                            {
                                _canBeFunction = (_curChar == '(');
                            }
                        }
                        if (!CheckOperator(false) && colonColon)
                        {
                            _axis = CheckAxis();
                        }
                    }
                    else
                    {
                        _kind = LexKind.Unknown;
                        NextChar();
                    }
                    break;
            }
        }
Example #7
0
 protected string AppendStep(string basePath, XPathAxis stepAxis, string stepNodeTest, string predicate)
 {
     return this.EnsureTrailingSlash(basePath) + this.GetAxisString(stepAxis) + stepNodeTest + this.EnsureBracketedPredicate(predicate);
 }
        private static QilLoop BuildAxisFilter(QilPatternFactory f, QilIterator itr, XPathAxis xpathAxis, XPathNodeType nodeType, string name, string nsUri) {
            QilNode nameTest = (
                name  != null && nsUri != null ? f.Eq(f.NameOf(itr), f.QName(name, nsUri))    : // ns:bar || bar
                nsUri != null                  ? f.Eq(f.NamespaceUriOf(itr), f.String(nsUri)) : // ns:*
                name  != null                  ? f.Eq(f.LocalNameOf(itr), f.String(name))     : // *:foo
                /*name  == nsUri == null*/       f.True()                                       // *
            );

            XmlNodeKindFlags intersection = XPathBuilder.AxisTypeMask(itr.XmlType.NodeKinds, nodeType, xpathAxis);

            QilNode typeTest = (
                intersection == 0                     ? f.False() :  // input & required doesn't intersect
                intersection == itr.XmlType.NodeKinds ? f.True()  :  // input is subset of required
                /*else*/                                f.IsType(itr, T.NodeChoice(intersection))
            );

            QilLoop filter = f.BaseFactory.Filter(itr, f.And(typeTest, nameTest));
            filter.XmlType = T.PrimeProduct(T.NodeChoice(intersection), filter.XmlType.Cardinality);

            return filter;
        }
        public QilNode Axis(XPathAxis xpathAxis, XPathNodeType nodeType, string prefix, string name) {
            Debug.Assert(
                xpathAxis == XPathAxis.Child ||
                xpathAxis == XPathAxis.Attribute ||
                xpathAxis == XPathAxis.DescendantOrSelf ||
                xpathAxis == XPathAxis.Root
            );
            QilLoop result;
            double  priority;
            switch (xpathAxis) {
            case XPathAxis.DescendantOrSelf :
                Debug.Assert(nodeType == XPathNodeType.All && prefix == null && name == null, " // is the only d-o-s axes that we can have in pattern");
                return f.Nop(this.fixupNode); // We using Nop as a flag that DescendantOrSelf exis was used between steps.
            case XPathAxis.Root :
                QilIterator i;
                result = f.BaseFactory.Filter(i = f.For(fixupNode), f.IsType(i, T.Document));
                priority = 0.5;
                break;
            default :
                string   nsUri = prefix == null ? null : this.environment.ResolvePrefix(prefix);
                result = BuildAxisFilter(f, f.For(fixupNode), xpathAxis, nodeType, name, nsUri);
                switch (nodeType) {
                case XPathNodeType.Element :
                case XPathNodeType.Attribute :
                    if (name != null) {
                        priority = 0;
                    } else {
                        if (prefix != null) {
                            priority = -0.25;
                        } else {
                            priority = -0.5;
                        }
                    }
                    break;
                case XPathNodeType.ProcessingInstruction :
                    priority = name != null ? 0 : -0.5;
                    break;
                default:
                    priority = -0.5;
                    break;
                }
                break;
            }

            SetPriority(result, priority);
            SetLastParent(result, result);
            return result;
        }
	public override object EvaluateInternal(XPathNodeIterator iterator)
#line 36 "./XPath/Private/XPathEvaluate.tc"
	{
		NodeTest node = this;
	
		// TODO handle various axes
		XPathSimpleIterator axis = null;
		
		switch(node.axis)
		{
			case XPathAxis.Self:
			{
				axis = new XPathSelfIterator(
										(XPathBaseIterator)iterator);
			}
			break;
			
			case XPathAxis.Child:
			{
				axis = new XPathChildIterator(
										(XPathBaseIterator)iterator);
			}
			break;
			
			case XPathAxis.Parent:
			{
				axis = new XPathParentIterator(
										(XPathBaseIterator)iterator);
			}
			break;
	
			case XPathAxis.Attribute:
			{
				axis = new XPathAttributeIterator(
										(XPathBaseIterator)iterator);
			}
			break;
	
			case XPathAxis.Ancestor:
			{
				axis = new XPathAncestorIterator(
										(XPathBaseIterator)iterator);
			}
			break;
			
			case XPathAxis.AncestorOrSelf:
			{
				axis = new XPathAncestorOrSelfIterator(
										(XPathBaseIterator)iterator);
			}
			break;
			
			case XPathAxis.Descendant:
			{
				axis = new XPathDescendantIterator(
										(XPathBaseIterator)iterator);
			}
			break;
			
			case XPathAxis.DescendantOrSelf:
			{
				axis = new XPathDescendantOrSelfIterator(
										(XPathBaseIterator)iterator);
			}
			break;
	
			case XPathAxis.Following:
			{
				axis = new XPathFollowingIterator(
										(XPathBaseIterator)iterator);
			}
			break;
	
			case XPathAxis.FollowingSibling:
			{
				axis = new XPathFollowingSiblingIterator(
										(XPathBaseIterator)iterator);
			}
			break;
			
			case XPathAxis.Preceding:
			{
				axis = new XPathPrecedingIterator(
										(XPathBaseIterator)iterator);
			}
			break;
			
			case XPathAxis.PrecedingSibling:
			{
				axis = new XPathPrecedingSiblingIterator(
										(XPathBaseIterator)iterator);
			}
			break;
	
			case XPathAxis.Namespace:
			{
				axis = new XPathNamespaceIterator(
										(XPathBaseIterator)iterator);
			}
			break;
			
			default:
			{
				throw new NotImplementedException(node.axis + " is not implemented");
			}
			break;
		}
		
		return new XPathAxisIterator(axis, this);
	}
	public NodeTest(XPathAxis axis, XPathNodeType nodeType, XmlQualifiedName name)
		: base()
	{
		this.kind__ = KIND;
		this.axis = axis;
		this.nodeType = nodeType;
		this.name = name;
	}
	public StepExpression(XPathAxis axis, Expression filter)
		: base()
	{
		this.kind__ = KIND;
		this.axis = axis;
		this.filter = filter;
	}