File: BaseAxisQuery.cs

package info (click to toggle)
mono 6.14.1%2Bds2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,282,732 kB
  • sloc: cs: 11,182,461; xml: 2,850,281; ansic: 699,123; cpp: 122,919; perl: 58,604; javascript: 30,841; asm: 21,845; makefile: 19,602; sh: 10,973; python: 4,772; pascal: 925; sql: 859; sed: 16; php: 1
file content (133 lines) | stat: -rw-r--r-- 5,207 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//------------------------------------------------------------------------------
// <copyright file="baseaxisquery.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>                                                                
// <owner current="true" primary="true">Microsoft</owner>
//------------------------------------------------------------------------------

namespace MS.Internal.Xml.XPath {
    using System;
    using System.Xml;
    using System.Xml.XPath;
    using System.Diagnostics;
    using System.Globalization;
    using System.Xml.Xsl;
    using System.Collections;

    internal abstract class BaseAxisQuery : Query {
        internal Query qyInput;
        bool nameTest;
        string name;
        string prefix;
        string nsUri;
        XPathNodeType typeTest;

        // these two things are the state of this class
        // that need to be reset whenever the context changes.
        protected XPathNavigator currentNode;
        protected int position;

        protected BaseAxisQuery(Query qyInput) {
            this.name = string.Empty;
            this.prefix = string.Empty;
            this.nsUri = string.Empty;
            this.qyInput = qyInput;
        }
        protected BaseAxisQuery(Query qyInput, string name, string prefix, XPathNodeType typeTest) {
            Debug.Assert(qyInput != null);
            this.qyInput  = qyInput;
            this.name     = name;
            this.prefix   = prefix;
            this.typeTest = typeTest;
            this.nameTest = prefix.Length != 0 || name.Length != 0;
            this.nsUri    = string.Empty;
        }
        protected BaseAxisQuery(BaseAxisQuery other) : base(other) {
            this.qyInput  = Clone(other.qyInput);
            this.name     = other.name;
            this.prefix   = other.prefix;
            this.nsUri    = other.nsUri;
            this.typeTest = other.typeTest;
            this.nameTest = other.nameTest;
            this.position = other.position;
            this.currentNode = other.currentNode;
        }

        public override void Reset() {
            position = 0;
            currentNode = null; // After this current will not point to context node from Evaluate() call
                                // But this is ok, becuase there is no public Reset() on XPathNodeIterator
            qyInput.Reset();
        }

        public override void SetXsltContext(XsltContext context) {
            Debug.Assert(context != null);
            nsUri = context.LookupNamespace(prefix);
            qyInput.SetXsltContext(context);
        }

        protected string        Name      { get { return name;     } }
        protected string        Prefix    { get { return prefix;   } }
        protected string        Namespace { get { return nsUri;    } }
        protected bool          NameTest  { get { return nameTest; } }
        protected XPathNodeType TypeTest  { get { return typeTest; } }

        public override int CurrentPosition { get { return position; } }
        public override XPathNavigator Current { get { return currentNode; } }

        public virtual bool matches(XPathNavigator e) {
            if (
                TypeTest == e.NodeType || 
                TypeTest == XPathNodeType.All ||
                TypeTest == XPathNodeType.Text && (e.NodeType == XPathNodeType.Whitespace || e.NodeType == XPathNodeType.SignificantWhitespace)
            ) {
                if (NameTest) {
                    if (name.Equals(e.LocalName) || name.Length == 0) {
                        if (nsUri.Equals(e.NamespaceURI)){
                            return true;
                        }
                    }
                } else {
                    return true;
                }
            }
            return false;       
        }

        public override object Evaluate(XPathNodeIterator nodeIterator) {
            ResetCount();
            Reset();
            qyInput.Evaluate(nodeIterator);
            AssertQuery(qyInput);
            return this;
        }
        
        public override double XsltDefaultPriority { get {
            if (qyInput.GetType() != typeof(ContextQuery)) {
                return 0.5;   // a/b a[b] id('s')/a
            }
            Debug.Assert(this is AttributeQuery || this is ChildrenQuery);
            if (name.Length != 0) {
                return 0; // p:foo, foo, processing-instruction("foo")
            }
            if (prefix.Length != 0) {
                return -0.25; // p:*
            }
            return -0.5; // *, text(), node()
        } }

        public override XPathResultType StaticType { get { return XPathResultType.NodeSet; } }

        public override void PrintQuery(XmlWriter w) {
            w.WriteStartElement(this.GetType().Name);
            if (NameTest) {
                w.WriteAttributeString("name", Prefix.Length != 0 ? Prefix + ':' + Name : Name);
            }
            if (TypeTest != XPathNodeType.Element) {
                w.WriteAttributeString("nodeType", TypeTest.ToString());
            }
            qyInput.PrintQuery(w);
            w.WriteEndElement();
        }
    }
}