5 // Ben Maurer (bmaurer@users.sourceforge.net)
6 // Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
9 // (C) 2003 Atsushi Enomoto
13 using System.Collections;
15 using System.Xml.XPath;
19 using QName = System.Xml.XmlQualifiedName;
21 namespace Mono.Xml.Xsl.Operations {
23 public class XslVariableInformation
26 XPathExpression select;
29 public XslVariableInformation (Compiler c)
31 c.AssertAttribute ("name");
32 name = c.ParseQNameAttribute ("name");
34 XmlConvert.VerifyName (name.Name);
35 } catch (XmlException ex) {
36 throw new XsltCompileException ("Variable name is not qualified name.", ex, c.Input);
39 string sel = c.GetAttribute ("select");
40 if (sel != null && sel != "" ) {
41 select = c.CompileExpression (c.GetAttribute ("select"));
43 } else if (c.Input.MoveToFirstChild ()) {
44 content = c.CompileTemplateContent ();
45 c.Input.MoveToParent ();
49 public object Evaluate (XslTransformProcessor p)
52 return p.Evaluate (select);
53 } else if (content != null) {
54 // XmlNodeWriter w = new XmlNodeWriter (false);
55 DTMXPathDocumentWriter w = new DTMXPathDocumentWriter (p.CurrentNode.NameTable, 200);
56 Outputter outputter = new GenericOutputter(w, p.Outputs, null, true);
57 p.PushOutput (outputter);
60 // return w.Document.CreateNavigator ().SelectChildren (XPathNodeType.All);
61 return w.CreateDocument ().CreateNavigator ().SelectChildren (XPathNodeType.All);
67 public QName Name { get { return name; }}
70 public abstract class XslGeneralVariable : XslCompiledElement, IXsltContextVariable {
71 protected XslVariableInformation var;
73 public XslGeneralVariable (Compiler c) : base (c) {}
75 protected override void Compile (Compiler c)
77 this.var = new XslVariableInformation (c);
80 public override abstract void Evaluate (XslTransformProcessor p);
81 protected abstract object GetValue (XslTransformProcessor p);
84 public object Evaluate (XsltContext xsltContext)
86 object value = GetValue (((XsltCompiledContext)xsltContext).Processor);
88 if (value is XPathNodeIterator)
89 return ((XPathNodeIterator)value).Clone ();
94 public QName Name {get {return var.Name;}}
95 public XPathResultType VariableType { get {return XPathResultType.Any;}}
96 public abstract bool IsLocal { get; }
97 public abstract bool IsParam { get; }
100 public class XslGlobalVariable : XslGeneralVariable {
101 public XslGlobalVariable (Compiler c) : base (c) {}
102 static object busyObject = new Object ();
105 public override void Evaluate (XslTransformProcessor p)
107 Hashtable varInfo = p.globalVariableTable;
109 if (varInfo.Contains (this)) {
110 if (varInfo [this] == busyObject)
111 throw new Exception ("Circular Dependency");
115 varInfo [this] = busyObject;
116 varInfo [this] = var.Evaluate (p);
120 protected override object GetValue (XslTransformProcessor p)
123 return p.globalVariableTable [this];
126 public override bool IsLocal { get { return false; }}
127 public override bool IsParam { get { return false; }}
130 public class XslGlobalParam : XslGlobalVariable {
134 public XslGlobalParam (Compiler c) : base (c) {}
136 public void Override (XslTransformProcessor p, object paramVal)
138 Debug.Assert (!p.globalVariableTable.Contains (this), "Shouldn't have been evaluated by this point");
140 p.globalVariableTable [this] = paramVal;
143 public override bool IsParam { get { return true; }}
146 public class XslLocalVariable : XslGeneralVariable {
149 public XslLocalVariable (Compiler c) : base (c)
151 slot = c.AddVariable (this);
154 public override void Evaluate (XslTransformProcessor p)
156 p.SetStackItem (slot, var.Evaluate (p));
159 protected override object GetValue (XslTransformProcessor p)
161 return p.GetStackItem (slot);
164 public bool IsEvaluated (XslTransformProcessor p)
166 return p.GetStackItem (slot) != null;
169 public override bool IsLocal { get { return true; }}
170 public override bool IsParam { get { return false; }}
173 public class XslLocalParam : XslLocalVariable {
177 public XslLocalParam (Compiler c) : base (c) {}
179 public override void Evaluate (XslTransformProcessor p)
181 if (p.GetStackItem (slot) != null) return; // evaluated already
186 public void Override (XslTransformProcessor p, object paramVal)
188 p.SetStackItem (slot, paramVal);
191 public override bool IsParam { get { return true; }}
194 internal class XPathVariableBinding : Expression {
195 XslGeneralVariable v;
196 public XPathVariableBinding (XslGeneralVariable v)
200 public override String ToString () { return "$" + v.Name.ToString (); }
201 public override XPathResultType ReturnType { get { return XPathResultType.Any; }}
202 public override XPathResultType GetReturnType (BaseIterator iter)
204 return XPathResultType.Any;
207 public override object Evaluate (BaseIterator iter)
209 return v.Evaluate (iter.NamespaceManager as XsltContext);