Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAtsushi Eno <atsushieno@gmail.com>2006-03-15 17:43:45 +0300
committerAtsushi Eno <atsushieno@gmail.com>2006-03-15 17:43:45 +0300
commita40a00bcde3ffd7a8a449596a2653d190f6e8b94 (patch)
treef35d0fe706dfa497c5c0e6c3d91fde08b08a5dc9 /mcs/class/System.XML/Mono.Xml.Xsl
parente8e59bb8cbdf347b704e34bfc9f342b3dc41f731 (diff)
2006-03-15 Atsushi Enomoto <atsushi@ximian.com>
* XslTransformProcessor.cs, Compiler.cs : eliminate ExpressionStore. Now sorting is done inside XslSortEvaluator. * XslSortEvaluator.cs : new file. It handles current node in XSLT context. Fixed bug #77781. * Expression.cs : extracted XPathSortElement, XPathSorters and XPathSorter from CompiledExpression, and split XPathSorters.Sort() into some methods. Those changes are to make them reusable in XslSortEvaluator. * System.Xml.dll.sources : added XslSortEvaluator.cs. * knownFailures.txt : removed two xsl:sort+current() tests. svn path=/trunk/mcs/; revision=58015
Diffstat (limited to 'mcs/class/System.XML/Mono.Xml.Xsl')
-rw-r--r--mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog8
-rw-r--r--mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs71
-rw-r--r--mcs/class/System.XML/Mono.Xml.Xsl/XslSortEvaluator.cs97
-rw-r--r--mcs/class/System.XML/Mono.Xml.Xsl/XslTransformProcessor.cs7
4 files changed, 121 insertions, 62 deletions
diff --git a/mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog b/mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog
index c7041f895a9..91022d9e95a 100644
--- a/mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog
+++ b/mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog
@@ -1,5 +1,13 @@
2006-03-15 Atsushi Enomoto <atsushi@ximian.com>
+ * XslTransformProcessor.cs,
+ Compiler.cs : eliminate ExpressionStore. Now sorting is done
+ inside XslSortEvaluator.
+ * XslSortEvaluator.cs : new file. It handles current node in XSLT
+ context. Fixed bug #77781.
+
+2006-03-15 Atsushi Enomoto <atsushi@ximian.com>
+
* XslTransformProcessor.cs : in PushNodeset() avoid Clone(). It saves
extra cost, and might avoid possible bug in for-each and current()
evaluation.
diff --git a/mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs b/mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs
index 8f90d24c00e..69d418a5e08 100644
--- a/mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs
+++ b/mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs
@@ -49,20 +49,18 @@ namespace Mono.Xml.Xsl
XslStylesheet style;
Hashtable globalVariables;
Hashtable attrSets;
- ExpressionStore exprStore;
XmlNamespaceManager nsMgr;
Hashtable keys;
Hashtable outputs;
Hashtable decimalFormats;
MSXslScriptManager msScripts;
- public CompiledStylesheet (XslStylesheet style, Hashtable globalVariables, Hashtable attrSets, ExpressionStore exprStore, XmlNamespaceManager nsMgr, Hashtable keys, Hashtable outputs, Hashtable decimalFormats,
+ public CompiledStylesheet (XslStylesheet style, Hashtable globalVariables, Hashtable attrSets, XmlNamespaceManager nsMgr, Hashtable keys, Hashtable outputs, Hashtable decimalFormats,
MSXslScriptManager msScripts)
{
this.style = style;
this.globalVariables = globalVariables;
this.attrSets = attrSets;
- this.exprStore = exprStore;
this.nsMgr = nsMgr;
this.keys = keys;
this.outputs = outputs;
@@ -71,7 +69,6 @@ namespace Mono.Xml.Xsl
}
public Hashtable Variables {get{return globalVariables;}}
public XslStylesheet Style { get { return style; }}
- public ExpressionStore ExpressionStore {get{return exprStore;}}
public XmlNamespaceManager NamespaceManager {get{return nsMgr;}}
public Hashtable Keys {get { return keys;}}
public Hashtable Outputs { get { return outputs; }}
@@ -118,7 +115,6 @@ namespace Mono.Xml.Xsl
Hashtable globalVariables = new Hashtable ();
Hashtable attrSets = new Hashtable ();
- ExpressionStore exprStore = new ExpressionStore ();
XmlNamespaceManager nsMgr = new XmlNamespaceManager (new NameTable ());
XmlResolver res;
@@ -165,7 +161,7 @@ namespace Mono.Xml.Xsl
throw new XsltCompileException ("XSLT compile error. " + x.Message, x, Input);
}
- return new CompiledStylesheet (rootStyle, globalVariables, attrSets, exprStore, nsMgr, keys, outputs, decimalFormats, msScripts);
+ return new CompiledStylesheet (rootStyle, globalVariables, attrSets, nsMgr, keys, outputs, decimalFormats, msScripts);
}
MSXslScriptManager msScripts = new MSXslScriptManager ();
@@ -354,7 +350,6 @@ namespace Mono.Xml.Xsl
Pattern p = Pattern.Compile (pattern, this);
if (p == null)
throw new XsltCompileException (String.Format ("Invalid pattern '{0}'", pattern), null, loc);
- exprStore.AddPattern (p, this);
return p;
}
@@ -375,8 +370,6 @@ namespace Mono.Xml.Xsl
expr = new ExprKeyContainer (expr);
CompiledExpression e = new CompiledExpression (expression, expr);
- exprStore.AddExpression (e, this);
-
return e;
}
@@ -441,10 +434,6 @@ namespace Mono.Xml.Xsl
return curVarScope.AddVariable (v);
}
- public void AddSort (XPathExpression e, Sort s)
- {
- exprStore.AddSort (e, s);
- }
public VariableScope CurrentVariableScope { get { return curVarScope; }}
#endregion
@@ -697,8 +686,11 @@ namespace Mono.Xml.Xsl
order = ParseOrder (XslAvt.AttemptPreCalc (ref orderAvt));
caseOrder = ParseCaseOrder (XslAvt.AttemptPreCalc (ref caseOrderAvt));
}
-
-
+
+ public bool IsContextDependent {
+ get { return orderAvt != null || caseOrderAvt != null || langAvt != null || dataTypeAvt != null; }
+ }
+
string ParseLang (string value)
{
return value;
@@ -755,48 +747,15 @@ namespace Mono.Xml.Xsl
dataTypeAvt == null ? dataType : ParseDataType (dataTypeAvt.Evaluate (p))
);
}
- }
-
- internal class ExpressionStore {
- Hashtable exprToSorts;
-
- public void AddExpression (XPathExpression e, Compiler c)
- {
- }
-
- public void AddPattern (Pattern p, Compiler c)
- {
- }
-
- public void AddSort (XPathExpression e, Sort s)
- {
- if (exprToSorts == null)
- exprToSorts = new Hashtable ();
-
- if (exprToSorts.Contains (e))
- ((ArrayList)exprToSorts [e]).Add (s);
- else {
- ArrayList a = new ArrayList ();
- a.Add (s);
- exprToSorts [e] = a;
- }
- }
-
- public XPathExpression PrepForExecution (XPathExpression e, XslTransformProcessor p)
- {
- if (exprToSorts != null && exprToSorts.Contains (e))
- {
- XPathExpression expr = e.Clone ();
- foreach (Sort s in (ArrayList)exprToSorts [e])
- s.AddToExpr (expr,p);
- return expr;
- }
- return e;
- }
-
- public bool PatternMatches (Pattern p, XslTransformProcessor proc, XPathNavigator n)
+
+ public XPathSorter ToXPathSorter (XslTransformProcessor p)
{
- return p.Matches (n, proc.XPathContext);
+ return new XPathSorter (expr,
+ orderAvt == null ? order : ParseOrder (orderAvt.Evaluate (p)),
+ caseOrderAvt == null ? caseOrder: ParseCaseOrder (caseOrderAvt.Evaluate (p)),
+ langAvt == null ? lang : ParseLang (langAvt.Evaluate (p)),
+ dataTypeAvt == null ? dataType : ParseDataType (dataTypeAvt.Evaluate (p))
+ );
}
}
diff --git a/mcs/class/System.XML/Mono.Xml.Xsl/XslSortEvaluator.cs b/mcs/class/System.XML/Mono.Xml.Xsl/XslSortEvaluator.cs
new file mode 100644
index 00000000000..482b19bb235
--- /dev/null
+++ b/mcs/class/System.XML/Mono.Xml.Xsl/XslSortEvaluator.cs
@@ -0,0 +1,97 @@
+//
+// XslSortEvaluator.cs
+//
+// Author:
+// Atsushi Enomoto (atsushi@ximian.com)
+//
+// Copyright (C) 2006 Novell, Inc. http://www.novell.com
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+//
+// This class handles xsl:sort to have XslTransformProcessor involved in
+// the evaluation of resulting nodeset. Beyond XPathExpression.AddSort(),
+// it handles current() by having .
+//
+using System;
+using System.Collections;
+using System.Xml;
+using System.Xml.XPath;
+
+namespace Mono.Xml.Xsl
+{
+ class XslSortEvaluator
+ {
+ public XslSortEvaluator (XPathExpression select, Sort [] sorterTemplates)
+ {
+ this.select = select;
+ this.sorterTemplates = sorterTemplates;
+ PopulateConstantSorters ();
+ sortRunner = new XPathSorters ();
+ }
+
+ XPathExpression select;
+ Sort [] sorterTemplates;
+ XPathSorter [] sorters;
+ XPathSorters sortRunner;
+ bool isSorterContextDependent;
+
+ void PopulateConstantSorters ()
+ {
+ sorters = new XPathSorter [sorterTemplates.Length];
+ for (int i = 0; i < sorterTemplates.Length; i++) {
+ Sort sort = sorterTemplates [i];
+ if (sort.IsContextDependent)
+ isSorterContextDependent = true;
+ else
+ sorters [i] = sort.ToXPathSorter (null);
+ }
+ }
+
+ public BaseIterator SortedSelect (XslTransformProcessor p)
+ {
+ if (isSorterContextDependent) {
+ for (int i = 0; i < sorters.Length; i++)
+ if (sorterTemplates [i].IsContextDependent)
+ sorters [i] = sorterTemplates [i].ToXPathSorter (p);
+ }
+ BaseIterator iter = (BaseIterator) p.Select (select);
+ p.PushNodeset (iter);
+ p.PushForEachContext ();
+ ArrayList list = new ArrayList (iter.Count);
+ while (iter.MoveNext ()) {
+ XPathSortElement item = new XPathSortElement ();
+ item.Navigator = iter.Current.Clone ();
+ item.Values = new object [sorters.Length];
+ for (int i = 0; i < sorters.Length; i++)
+ item.Values [i] = sorters [i].Evaluate (iter);
+ list.Add (item);
+ }
+ p.PopForEachContext ();
+ p.PopNodeset ();
+
+ sortRunner.CopyFrom (sorters);
+ return sortRunner.Sort (list, iter.NamespaceManager);
+ }
+ }
+}
diff --git a/mcs/class/System.XML/Mono.Xml.Xsl/XslTransformProcessor.cs b/mcs/class/System.XML/Mono.Xml.Xsl/XslTransformProcessor.cs
index d766a98bfd5..f7bb097f4d4 100644
--- a/mcs/class/System.XML/Mono.Xml.Xsl/XslTransformProcessor.cs
+++ b/mcs/class/System.XML/Mono.Xml.Xsl/XslTransformProcessor.cs
@@ -460,40 +460,35 @@ namespace Mono.Xml.Xsl {
public bool Matches (Pattern p, XPathNavigator n)
{
- return CompiledStyle.ExpressionStore.PatternMatches (p, this, n);
+ return p.Matches (n, this.XPathContext);
}
public object Evaluate (XPathExpression expr)
{
- expr = CompiledStyle.ExpressionStore.PrepForExecution (expr, this);
XPathNodeIterator itr = CurrentNodeset;
return itr.Current.Evaluate (expr, itr, XPathContext);
}
public string EvaluateString (XPathExpression expr)
{
- expr = CompiledStyle.ExpressionStore.PrepForExecution (expr, this);
XPathNodeIterator itr = CurrentNodeset;
return itr.Current.EvaluateString (expr, itr, XPathContext);
}
public bool EvaluateBoolean (XPathExpression expr)
{
- expr = CompiledStyle.ExpressionStore.PrepForExecution (expr, this);
XPathNodeIterator itr = CurrentNodeset;
return itr.Current.EvaluateBoolean (expr, itr, XPathContext);
}
public double EvaluateNumber (XPathExpression expr)
{
- expr = CompiledStyle.ExpressionStore.PrepForExecution (expr, this);
XPathNodeIterator itr = CurrentNodeset;
return itr.Current.EvaluateNumber (expr, itr, XPathContext);
}
public XPathNodeIterator Select (XPathExpression expr)
{
- expr = CompiledStyle.ExpressionStore.PrepForExecution (expr, this);
return CurrentNodeset.Current.Select (expr, XPathContext);
}