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 public override XPathResultType ReturnType {
\r
67 get { return expr.ReturnType; }
\r
70 public override bool RequireSorting {
78 CompiledExpression usePattern;
79 CompiledExpression matchPattern;
81 Hashtable mappedDocuments;
83 public XslKey (Compiler c)
85 this.name = c.ParseQNameAttribute ("name");
87 c.KeyCompilationMode = true;
88 usePattern = c.CompileExpression (c.GetAttribute ("use"));
89 if (usePattern == null)
90 usePattern = c.CompileExpression (".");
92 c.AssertAttribute ("match");
93 string matchString = c.GetAttribute ("match");
94 this.matchPattern = c.CompileExpression (matchString, true);
95 c.KeyCompilationMode = false;
98 public QName Name { get { return name; }}
99 internal CompiledExpression UsePattern { get { return usePattern; }}
100 internal CompiledExpression MatchPattern { get { return matchPattern; }}
102 internal void ClearKeyTable ()
108 if (mappedDocuments != null) {
109 mappedDocuments.Clear ();
110 mappedDocuments = null;
114 private void CollectTable (XPathNavigator doc)
116 XPathNavigator nav = doc.Clone ();
120 if (nav.Matches (MatchPattern))
122 } while (MoveNavigatorToNext (nav));
125 private bool MoveNavigatorToNext (XPathNavigator nav)
127 if (nav.MoveToFirstChild ())
130 if (nav.MoveToNext ())
132 } while (nav.MoveToParent ());
136 private void CollectIndex (XPathNavigator nav)
138 XPathNavigator target = nav.Clone ();
139 XPathNodeIterator iter;
140 switch (UsePattern.ReturnType) {
141 case XPathResultType.NodeSet:
142 iter = nav.Select (UsePattern);
143 while (iter.MoveNext ())
144 AddIndex (iter.Current.Value, target);
146 case XPathResultType.Any:
147 object o = nav.Evaluate (UsePattern);
148 iter = o as XPathNodeIterator;
150 while (iter.MoveNext ())
151 AddIndex (iter.Current.Value, target);
154 AddIndex (nav.EvaluateString (UsePattern, null, null), target);
157 string key = nav.EvaluateString (UsePattern, null, null);
158 AddIndex (key, target);
163 private void AddIndex (string key, XPathNavigator target)
165 ArrayList al = map [key] as ArrayList;
167 al = new ArrayList ();
173 public bool Matches (XPathNavigator nav, XmlNamespaceManager nsmgr, string value)
176 mappedDocuments = new Hashtable ();
177 map = new Hashtable ();
179 if (!mappedDocuments.ContainsKey (nav.BaseURI)) {
180 mappedDocuments.Add (nav.BaseURI, nav.BaseURI);
181 MatchPattern.SetContext (nsmgr);
182 UsePattern.SetContext (nsmgr);
184 MatchPattern.SetContext (null);
185 UsePattern.SetContext (null);
188 ArrayList al = map [value] as ArrayList;
191 for (int i = 0; i < al.Count; i++)
192 if (((XPathNavigator) al [i]).IsSamePosition (nav))