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;
18 using QName = System.Xml.XmlQualifiedName;
20 namespace Mono.Xml.Xsl.Operations {
22 public class XslVariableInformation
25 XPathExpression select;
28 public XslVariableInformation (Compiler c)
30 c.AssertAttribute ("name");
31 name = c.ParseQNameAttribute ("name");
33 string sel = c.GetAttribute ("select");
34 if (sel != null && sel != "" ) {
35 select = c.CompileExpression (c.GetAttribute ("select"));
37 } else if (c.Input.MoveToFirstChild ()) {
38 content = c.CompileTemplateContent ();
39 c.Input.MoveToParent ();
43 public object Evaluate (XslTransformProcessor p)
46 return p.Evaluate (select);
47 } else if (content != null) {
48 XmlNodeWriter w = new XmlNodeWriter ();
49 //TODO: which outputter should be used here?
50 Outputter outputter = new XmlOutputter(w, p.CompiledStyle.Style.Outputs);
51 p.PushOutput (outputter);
54 return w.Document.CreateNavigator ().SelectChildren (XPathNodeType.All);
60 public QName Name { get { return name; }}
63 public abstract class XslGeneralVariable : XslCompiledElement, IXsltContextVariable {
64 protected XslVariableInformation var;
66 public XslGeneralVariable (Compiler c) : base (c) {}
68 protected override void Compile (Compiler c)
70 this.var = new XslVariableInformation (c);
73 public override abstract void Evaluate (XslTransformProcessor p);
74 protected abstract object GetValue (XslTransformProcessor p);
77 public object Evaluate (XsltContext xsltContext)
79 object value = GetValue (((XsltCompiledContext)xsltContext).Processor);
81 if (value is XPathNodeIterator)
82 return ((XPathNodeIterator)value).Clone ();
87 public QName Name {get {return var.Name;}}
88 public XPathResultType VariableType { get {return XPathResultType.Any;}}
89 public abstract bool IsLocal { get; }
90 public abstract bool IsParam { get; }
93 public class XslGlobalVariable : XslGeneralVariable {
94 public XslGlobalVariable (Compiler c) : base (c) {}
95 static object busyObject = new Object ();
98 public override void Evaluate (XslTransformProcessor p)
100 Hashtable varInfo = p.globalVariableTable;
102 if (varInfo.Contains (this)) {
103 if (varInfo [this] == busyObject)
104 throw new Exception ("Circular Dependency");
108 varInfo [this] = busyObject;
109 varInfo [this] = var.Evaluate (p);
113 protected override object GetValue (XslTransformProcessor p)
116 return p.globalVariableTable [this];
119 public override bool IsLocal { get { return false; }}
120 public override bool IsParam { get { return false; }}
123 public class XslGlobalParam : XslGlobalVariable {
127 public XslGlobalParam (Compiler c) : base (c) {}
129 public void Override (XslTransformProcessor p, object paramVal)
131 Debug.Assert (!p.globalVariableTable.Contains (this), "Shouldn't have been evaluated by this point");
133 p.globalVariableTable [this] = paramVal;
136 public override bool IsParam { get { return true; }}
139 public class XslLocalVariable : XslGeneralVariable {
142 public XslLocalVariable (Compiler c) : base (c)
144 slot = c.AddVariable (this);
147 public override void Evaluate (XslTransformProcessor p)
149 p.SetStackItem (slot, var.Evaluate (p));
152 protected override object GetValue (XslTransformProcessor p)
154 return p.GetStackItem (slot);
157 public bool IsEvaluated (XslTransformProcessor p)
159 return p.GetStackItem (slot) != null;
162 public override bool IsLocal { get { return true; }}
163 public override bool IsParam { get { return false; }}
166 public class XslLocalParam : XslLocalVariable {
170 public XslLocalParam (Compiler c) : base (c) {}
172 public override void Evaluate (XslTransformProcessor p)
174 if (p.GetStackItem (slot) != null) return; // evaluated already
179 public void Override (XslTransformProcessor p, object paramVal)
181 p.SetStackItem (slot, paramVal);
184 public override bool IsParam { get { return true; }}