5 // Ben Maurer (bmaurer@users.sourceforge.net)
6 // Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
9 // (C) 2003 Atsushi Enomoto
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections;
35 using System.Collections.Specialized;
37 using System.Xml.Schema;
38 using System.Xml.XPath;
41 using QName = System.Xml.XmlQualifiedName;
43 namespace Mono.Xml.Xsl
45 internal class ExprKeyContainer : Expression
48 public ExprKeyContainer (Expression expr)
53 public Expression BodyExpression {
57 public override object Evaluate (BaseIterator iter)
59 return expr.Evaluate (iter);
62 internal override XPathNodeType EvaluatedNodeType {
\r
63 get { return expr.EvaluatedNodeType; }
\r
66 internal override bool NeedAbsoluteMatching {
\r
67 // This must be evaluated at any point.
\r
68 get { return true; }
\r
71 public override XPathResultType ReturnType {
\r
72 get { return expr.ReturnType; }
\r
75 public override bool RequireSorting {
83 CompiledExpression usePattern;
84 CompiledExpression matchPattern;
86 Hashtable mappedDocuments;
88 public XslKey (Compiler c)
90 this.name = c.ParseQNameAttribute ("name");
92 c.KeyCompilationMode = true;
93 usePattern = c.CompileExpression (c.GetAttribute ("use"));
94 if (usePattern == null)
95 usePattern = c.CompileExpression (".");
97 c.AssertAttribute ("match");
98 string matchString = c.GetAttribute ("match");
99 this.matchPattern = c.CompileExpression (matchString, true);
100 c.KeyCompilationMode = false;
103 public QName Name { get { return name; }}
104 internal CompiledExpression UsePattern { get { return usePattern; }}
105 internal CompiledExpression MatchPattern { get { return matchPattern; }}
107 internal void ClearKeyTable ()
113 if (mappedDocuments != null) {
114 mappedDocuments.Clear ();
115 mappedDocuments = null;
119 internal void CollectTable (XPathNavigator doc)
121 XPathNavigator nav = doc.Clone ();
123 // Expression expr = ((ExprKeyContainer) MatchPattern.ExpressionNode).BodyExpression;
124 // if (expr.NeedAbsoluteMatching)
125 // CollectAbsoluteMatchNodes (nav);
127 CollectRelativeMatchNodes (nav);
130 private void CollectAbsoluteMatchNodes (XPathNavigator nav)
132 XPathNodeIterator iter = nav.Select (MatchPattern);
133 while (iter.MoveNext ())
134 CollectIndex (iter.Current);
137 private void CollectRelativeMatchNodes (XPathNavigator nav)
140 if (nav.NodeType != XPathNodeType.Root)
141 while (!nav.MoveToNext ())
142 if (!nav.MoveToParent ())
147 if (nav.Matches (MatchPattern))
149 } while (nav.MoveToFirstChild ());
150 } while (nav.MoveToNext ());
151 } while (nav.MoveToParent ());
154 private void CollectIndex (XPathNavigator nav)
156 XPathNavigator target = nav.Clone ();
157 XPathNodeIterator iter;
158 switch (UsePattern.ReturnType) {
159 case XPathResultType.NodeSet:
160 iter = nav.Select (UsePattern);
161 while (iter.MoveNext ())
162 AddIndex (iter.Current.Value, target);
164 case XPathResultType.Any:
165 object o = nav.Evaluate (UsePattern);
166 iter = o as XPathNodeIterator;
168 while (iter.MoveNext ())
169 AddIndex (iter.Current.Value, target);
172 AddIndex (nav.EvaluateString (UsePattern, null, null), target);
175 string key = nav.EvaluateString (UsePattern, null, null);
176 AddIndex (key, target);
181 private void AddIndex (string key, XPathNavigator target)
183 ArrayList al = map [key] as ArrayList;
185 al = new ArrayList ();
191 public bool Matches (XPathNavigator nav, XmlNamespaceManager nsmgr, string value)
194 mappedDocuments = new Hashtable ();
195 map = new Hashtable ();
197 if (mappedDocuments [nav.BaseURI] == null) {
198 mappedDocuments.Add (nav.BaseURI, nav.BaseURI);
199 MatchPattern.SetContext (nsmgr);
200 UsePattern.SetContext (nsmgr);
202 MatchPattern.SetContext (null);
203 UsePattern.SetContext (null);
206 ArrayList al = map [value] as ArrayList;
209 for (int i = 0; i < al.Count; i++)
210 if (((XPathNavigator) al [i]).IsSamePosition (nav))