diff options
author | Atsushi Eno <atsushieno@gmail.com> | 2005-03-22 10:39:29 +0300 |
---|---|---|
committer | Atsushi Eno <atsushieno@gmail.com> | 2005-03-22 10:39:29 +0300 |
commit | ce6759fea0f857fe160606d6784e624c40a4428c (patch) | |
tree | 31380db1c3ae3dc0f5d0bf44e409c302dd88198d /mcs/class/System.XML/Mono.Xml.Xsl | |
parent | 30edd43bb79e9717acb2691c2c4b83edf5e34612 (diff) |
2004-03-22 Atsushi Enomoto <atsushi@ximian.com>
* Compiler.cs : Now it holds XPath parser and XSLT pattern parser.
* XslKey.cs : Use XSLT pattern parser for match.
UsePattern is now "Use" (it is not a pattern).
Reimplemented Evaluate() to make full use of index table.
Added Matches() to handle shorter match evaluation. For const value
for key (e.g. key patterns), it could avoid Evaluate().
* XsltCompiledContext.cs : Added MatchesKey() that just delegates to
new KeyIndexTable.Matches().
* XslFunctions.cs : Added PatternMatches() that just delegates to new
XsltCompiledContext.MatchesKey().
* Pattern.cs : Pattern.Compile() now uses XSLT pattern parser instead
of XPath parser.
* KeyPattern.cs : Matches() now just delegates to XsltKey.MatchesKey().
svn path=/trunk/mcs/; revision=42066
Diffstat (limited to 'mcs/class/System.XML/Mono.Xml.Xsl')
-rw-r--r-- | mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog | 13 | ||||
-rw-r--r-- | mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs | 8 | ||||
-rwxr-xr-x | mcs/class/System.XML/Mono.Xml.Xsl/XslFunctions.cs | 11 | ||||
-rw-r--r-- | mcs/class/System.XML/Mono.Xml.Xsl/XslKey.cs | 107 | ||||
-rw-r--r-- | mcs/class/System.XML/Mono.Xml.Xsl/XsltCompiledContext.cs | 9 |
5 files changed, 114 insertions, 34 deletions
diff --git a/mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog b/mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog index a972823a45e..1b43f5ad841 100644 --- a/mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog +++ b/mcs/class/System.XML/Mono.Xml.Xsl/ChangeLog @@ -1,5 +1,18 @@ 2005-03-22 Atsushi Enomoto <atsushi@ximian.com> + * Compiler.cs : Now it holds XPath parser and XSLT pattern parser. + * XslKey.cs : Use XSLT pattern parser for match. + UsePattern is now "Use" (it is not a pattern). + Reimplemented Evaluate() to make full use of index table. + Added Matches() to handle shorter match evaluation. For const value + for key (e.g. key patterns), it could avoid Evaluate(). + * XsltCompiledContext.cs : Added MatchesKey() that just delegates to + new KeyIndexTable.Matches(). + * XslFunctions.cs : Added PatternMatches() that just delegates to new + XsltCompiledContext.MatchesKey(). + +2005-03-22 Atsushi Enomoto <atsushi@ximian.com> + * GenericOutputter.cs : commented out warned fields. 2005-03-15 Atsushi Enomoto <atsushi@ximian.com> diff --git a/mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs b/mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs index ccb82f2627d..6787b9f5a3f 100644 --- a/mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs +++ b/mcs/class/System.XML/Mono.Xml.Xsl/Compiler.cs @@ -127,7 +127,8 @@ namespace Mono.Xml.Xsl public CompiledStylesheet Compile (XPathNavigator nav, XmlResolver res, Evidence evidence) { - this.parser = new XPathParser (this); + this.xpathParser = new XPathParser (this); + this.patternParser = new XsltPatternParser (this); this.res = res; if (res == null) this.res = new XmlUrlResolver (); @@ -350,7 +351,8 @@ namespace Mono.Xml.Xsl return p; } - internal XPathParser parser; + internal XPathParser xpathParser; + internal XsltPatternParser patternParser; internal CompiledExpression CompileExpression (string expression) { return CompileExpression (expression, false); @@ -360,7 +362,7 @@ namespace Mono.Xml.Xsl { if (expression == null || expression == "") return null; - Expression expr = parser.Compile (expression); + Expression expr = xpathParser.Compile (expression); if (isKey) expr = new ExprKeyContainer (expr); CompiledExpression e = new CompiledExpression (expression, expr); diff --git a/mcs/class/System.XML/Mono.Xml.Xsl/XslFunctions.cs b/mcs/class/System.XML/Mono.Xml.Xsl/XslFunctions.cs index f581eaab1ea..1c8d068a242 100755 --- a/mcs/class/System.XML/Mono.Xml.Xsl/XslFunctions.cs +++ b/mcs/class/System.XML/Mono.Xml.Xsl/XslFunctions.cs @@ -546,7 +546,16 @@ namespace Mono.Xml.Xsl internal override bool Peer { get { return arg0.Peer && arg1.Peer; } } - + + public bool PatternMatches (XPathNavigator nav, XsltContext nsmgr) + { + XsltCompiledContext ctx = nsmgr as XsltCompiledContext; + // for key pattern, it must contain literal value + return ctx.MatchesKey (nav, staticContext, + arg0.StaticValueAsString, + arg1.StaticValueAsString); + } + public override object Evaluate (BaseIterator iter) { XsltCompiledContext ctx = iter.NamespaceManager diff --git a/mcs/class/System.XML/Mono.Xml.Xsl/XslKey.cs b/mcs/class/System.XML/Mono.Xml.Xsl/XslKey.cs index 9873b817018..b1c61826274 100644 --- a/mcs/class/System.XML/Mono.Xml.Xsl/XslKey.cs +++ b/mcs/class/System.XML/Mono.Xml.Xsl/XslKey.cs @@ -37,6 +37,7 @@ using System.Xml; using System.Xml.Schema; using System.Xml.XPath; using System.Xml.Xsl; +using Mono.Xml.XPath; using QName = System.Xml.XmlQualifiedName; @@ -75,8 +76,8 @@ namespace Mono.Xml.Xsl internal class XslKey { QName name; - CompiledExpression usePattern; - CompiledExpression matchPattern; + CompiledExpression useExpr; + Pattern matchPattern; // Hashtable map; // Hashtable mappedDocuments; @@ -85,19 +86,19 @@ namespace Mono.Xml.Xsl this.name = c.ParseQNameAttribute ("name"); c.KeyCompilationMode = true; - usePattern = c.CompileExpression (c.GetAttribute ("use")); - if (usePattern == null) - usePattern = c.CompileExpression ("."); + useExpr = c.CompileExpression (c.GetAttribute ("use")); + if (useExpr == null) + useExpr = c.CompileExpression ("."); c.AssertAttribute ("match"); string matchString = c.GetAttribute ("match"); - this.matchPattern = c.CompileExpression (matchString, true); + this.matchPattern = c.CompilePattern (matchString, c.Input); c.KeyCompilationMode = false; } public QName Name { get { return name; }} - internal CompiledExpression UsePattern { get { return usePattern; }} - internal CompiledExpression MatchPattern { get { return matchPattern; }} + internal CompiledExpression Use { get { return useExpr; }} + internal Pattern Match { get { return matchPattern; }} } // represents part of dynamic context that holds index table for a key @@ -118,18 +119,21 @@ namespace Mono.Xml.Xsl get { return key; } } - private void CollectTable (XPathNavigator doc) + private void CollectTable (XPathNavigator doc, XsltContext ctx) { XPathNavigator nav = doc.Clone (); nav.MoveToRoot (); XPathNavigator tmp = doc.Clone (); do { - if (nav.Matches (key.MatchPattern)) { + if (key.Match.Matches (nav, ctx)) { tmp.MoveTo (nav); CollectIndex (nav, tmp); } } while (MoveNavigatorToNext (nav)); + if (map != null) + foreach (ArrayList list in map.Values) + list.Sort (XPathNavigatorComparer.Instance); } private bool MoveNavigatorToNext (XPathNavigator nav) @@ -146,24 +150,24 @@ namespace Mono.Xml.Xsl private void CollectIndex (XPathNavigator nav, XPathNavigator target) { XPathNodeIterator iter; - switch (key.UsePattern.ReturnType) { + switch (key.Use.ReturnType) { case XPathResultType.NodeSet: - iter = nav.Select (key.UsePattern); + iter = nav.Select (key.Use); while (iter.MoveNext ()) AddIndex (iter.Current.Value, target); break; case XPathResultType.Any: - object o = nav.Evaluate (key.UsePattern); + object o = nav.Evaluate (key.Use); iter = o as XPathNodeIterator; if (iter != null) { while (iter.MoveNext ()) AddIndex (iter.Current.Value, target); } else - AddIndex (nav.EvaluateString (key.UsePattern, null, null), target); + AddIndex (XPathFunctions.ToString (o), target); break; default: - string keyValue = nav.EvaluateString (key.UsePattern, null, null); + string keyValue = nav.EvaluateString (key.Use, null, null); AddIndex (keyValue, target); break; } @@ -182,7 +186,7 @@ namespace Mono.Xml.Xsl al.Add (target.Clone ()); } - public bool Matches (XPathNavigator nav, string value) + private ArrayList GetNodesByValue (XPathNavigator nav, string value, XsltContext ctx) { if (map == null) { mappedDocuments = new Hashtable (); @@ -190,14 +194,15 @@ namespace Mono.Xml.Xsl } if (!mappedDocuments.ContainsKey (nav.BaseURI)) { mappedDocuments.Add (nav.BaseURI, nav.BaseURI); - key.MatchPattern.SetContext (ctx); - key.UsePattern.SetContext (ctx); - CollectTable (nav); - key.MatchPattern.SetContext (null); - key.UsePattern.SetContext (null); + CollectTable (nav, ctx); } - ArrayList al = map [value] as ArrayList; + return map [value] as ArrayList; + } + + public bool Matches (XPathNavigator nav, string value, XsltContext ctx) + { + ArrayList al = GetNodesByValue (nav, value, ctx); if (al == null) return false; for (int i = 0; i < al.Count; i++) @@ -207,38 +212,79 @@ namespace Mono.Xml.Xsl } // Invoked from XsltKey (XPathFunction) - public object Evaluate (BaseIterator iter, + public BaseIterator Evaluate (BaseIterator iter, Expression valueExpr) { + /* ArrayList result = new ArrayList (); object o = valueExpr.Evaluate (iter); XPathNodeIterator it = o as XPathNodeIterator; - + XsltContext ctx = iter.NamespaceManager as XsltContext; + if (it != null) { while (it.MoveNext()) - FindKeyMatch (it.Current.Value, result, iter.Current); + FindKeyMatch (it.Current.Value, result, iter.Current, ctx); } else { - FindKeyMatch (XPathFunctions.ToString (o), result, iter.Current); + FindKeyMatch (XPathFunctions.ToString (o), result, iter.Current, ctx); } result.Sort (XPathNavigatorComparer.Instance); return new ListIterator (result, (ctx)); + */ + + XPathNodeIterator i = iter; + if (iter.CurrentPosition == 0) { + i = iter.Clone (); + i.MoveNext (); + } + XPathNavigator nav = i.Current; + + object o = valueExpr.Evaluate (iter); + XPathNodeIterator it = o as XPathNodeIterator; + XsltContext ctx = iter.NamespaceManager as XsltContext; + + BaseIterator result = null; + + if (it != null) { + while (it.MoveNext()) { + ArrayList nodes = GetNodesByValue ( + it.Current, it.Current.Value, ctx); + if (nodes == null) + continue; + ListIterator tmp = + new ListIterator (nodes, ctx); + if (result == null) + result = tmp; + else + result = new UnionIterator ( + iter, result, tmp); + } + } + else { + ArrayList nodes = GetNodesByValue ( + nav, XPathFunctions.ToString (o), ctx); + if (nodes != null) + result = new ListIterator (nodes, ctx); + } + + return result != null ? result : new NullIterator (iter); } - void FindKeyMatch (string value, ArrayList result, XPathNavigator context) + /* + void FindKeyMatch (string value, ArrayList result, XPathNavigator context, XsltContext xsltContext) { - XPathNavigator searchDoc = context.Clone (); + XPathNavigator searchDoc = context;//.Clone (); searchDoc.MoveToRoot (); if (key != null) { XPathNodeIterator desc = searchDoc.SelectDescendants (XPathNodeType.All, true); while (desc.MoveNext ()) { - if (Matches (desc.Current, value)) + if (Matches (desc.Current, value, xsltContext)) AddResult (result, desc.Current); if (!desc.Current.MoveToFirstAttribute ()) continue; do { - if (Matches (desc.Current, value)) + if (Matches (desc.Current, value, xsltContext)) AddResult (result, desc.Current); } while (desc.Current.MoveToNextAttribute ()); @@ -261,5 +307,6 @@ namespace Mono.Xml.Xsl } result.Add (nav.Clone ()); } + */ } }
\ No newline at end of file diff --git a/mcs/class/System.XML/Mono.Xml.Xsl/XsltCompiledContext.cs b/mcs/class/System.XML/Mono.Xml.Xsl/XsltCompiledContext.cs index 6c69260e1a8..34ee18e2f48 100644 --- a/mcs/class/System.XML/Mono.Xml.Xsl/XsltCompiledContext.cs +++ b/mcs/class/System.XML/Mono.Xml.Xsl/XsltCompiledContext.cs @@ -83,6 +83,15 @@ namespace Mono.Xml.Xsl return table.Evaluate (iter, valueExpr); } + public bool MatchesKey (XPathNavigator nav, + IStaticXsltContext staticContext, + string name, string value) + { + QName qname = XslNameUtil.FromString (name, staticContext); + KeyIndexTable table = GetIndexTable (qname); + return table.Matches (nav, value, this); + } + private QName GetKeyName (IStaticXsltContext staticContext, BaseIterator iter, Expression nameExpr) { |