(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / System.XML / Mono.Xml.XPath / LocationPathPattern.cs
blob7853d83b6e3ea6af06cf88ca2b5257d5c141a3d9
1 //
2 // Mono.Xml.XPath.LocationPathPattern
3 //
4 // Author:
5 // Ben Maurer (bmaurer@users.sourceforge.net)
6 //
7 // (C) 2003 Ben Maurer
8 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System;
32 using System.Collections;
33 using System.IO;
34 using System.Xml;
35 using System.Xml.Schema;
36 using System.Xml.XPath;
37 using System.Xml.Xsl;
39 namespace Mono.Xml.XPath {
40 internal class LocationPathPattern : Pattern {
42 LocationPathPattern patternPrevious;
43 bool isAncestor;
44 NodeTest nodeTest;
45 ExprFilter filter;
46 XPathNavigator previousNavigator;
48 public LocationPathPattern (NodeTest nodeTest)
50 this.nodeTest = nodeTest;
53 public LocationPathPattern (ExprFilter filter)
55 this.filter = filter;
57 while (! (filter.expr is NodeTest))
58 filter = (ExprFilter)filter.expr;
60 this.nodeTest = (NodeTest)filter.expr;
63 internal void SetPreviousPattern (Pattern prev, bool isAncestor)
65 LocationPathPattern toSet = LastPathPattern;
66 toSet.patternPrevious = (LocationPathPattern)prev;
67 toSet.isAncestor = isAncestor;
70 public override double DefaultPriority {
71 get {
72 if (patternPrevious == null && filter == null) {
73 NodeNameTest t = nodeTest as NodeNameTest;
74 if (t != null) {
75 if (t.Name.Name == "*")
76 return -.25;
77 return 0;
80 return -.5;
82 return .5;
86 public override bool Matches (XPathNavigator node, XsltContext ctx)
88 if (! nodeTest.Match (ctx, node))
89 return false;
91 if (nodeTest is NodeTypeTest) {
92 // node () is different in xslt patterns
93 if (((NodeTypeTest)nodeTest).type == XPathNodeType.All &&
94 (node.NodeType == XPathNodeType.Root ||
95 node.NodeType == XPathNodeType.Attribute)
97 return false;
100 if (filter == null && patternPrevious == null)
101 return true;
103 if (patternPrevious != null) {
104 if (!isAncestor) {
105 XPathNavigator parent = node.Clone ();
106 parent.MoveToParent ();
107 if (!patternPrevious.Matches (parent, ctx))
108 return false;
109 } else {
110 XPathNavigator anc = node.Clone ();
111 while (true) {
112 if (!anc.MoveToParent ())
113 return false;
115 if (patternPrevious.Matches (anc, ctx))
116 break;
122 if (filter == null)
123 return true;
125 // Optimization for non-positional predicate
126 if (!filter.IsPositional && !(filter.expr is ExprFilter)) {
127 return filter.pred.EvaluateBoolean (new NullIterator (node, ctx));
130 XPathNavigator p = null;
131 if (previousNavigator == node) {
132 p = previousNavigator;
133 p.MoveTo (node);
134 } else {
135 p = node.Clone ();
136 previousNavigator = p;
138 p.MoveToParent ();
140 BaseIterator matches = filter.EvaluateNodeSet (new NullIterator (p, ctx));
142 while (matches.MoveNext ()) {
143 if (node.IsSamePosition (matches.Current))
144 return true;
147 return false;
150 public override string ToString ()
152 string ret = "";
153 if (patternPrevious != null) ret = patternPrevious.ToString () + (isAncestor ? "//" : "/");
154 if (filter != null) ret += filter.ToString ();
155 else ret += nodeTest.ToString ();
157 return ret;
160 public LocationPathPattern LastPathPattern {
161 get {
162 LocationPathPattern ret = this;
164 while (ret.patternPrevious != null)
165 ret = ret.patternPrevious;
167 return ret;