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 ();
52 return w.Document.CreateNavigator ().SelectChildren (XPathNodeType.All);
58 public QName Name { get { return name; }}
61 public abstract class XslGeneralVariable : XslCompiledElement, IXsltContextVariable {
62 protected XslVariableInformation var;
64 public XslGeneralVariable (Compiler c) : base (c) {}
66 protected override void Compile (Compiler c)
68 this.var = new XslVariableInformation (c);
71 public override abstract void Evaluate (XslTransformProcessor p);
72 protected abstract object GetValue (XslTransformProcessor p);
75 public object Evaluate (XsltContext xsltContext)
77 XslTransformProcessor p = ((XsltCompiledContext)xsltContext).Processor;
80 object value = GetValue (p);
82 if (value is XPathNodeIterator)
83 return ((XPathNodeIterator)value).Clone ();
88 public QName Name {get {return var.Name;}}
89 public XPathResultType VariableType { get {return XPathResultType.Any;}}
90 public abstract bool IsLocal { get; }
91 public abstract bool IsParam { get; }
94 public class XslGlobalVariable : XslGeneralVariable {
95 public XslGlobalVariable (Compiler c) : base (c) {}
96 static object busyObject = new Object ();
99 public override void Evaluate (XslTransformProcessor p)
101 Hashtable varInfo = p.globalVariableTable;
103 if (varInfo.Contains (this)) {
104 if (varInfo [this] == busyObject)
105 throw new Exception ("Circular Dependency");
109 varInfo [this] = busyObject;
110 varInfo [this] = var.Evaluate (p);
114 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 override bool IsLocal { get { return true; }}
158 public override bool IsParam { get { return false; }}
161 public class XslLocalParam : XslLocalVariable {
165 public XslLocalParam (Compiler c) : base (c) {}
167 public override void Evaluate (XslTransformProcessor p)
169 if (p.GetStackItem (slot) != null) return; // evaluated already
174 public void Override (XslTransformProcessor p, object paramVal)
176 p.SetStackItem (slot, paramVal);
179 public override bool IsParam { get { return true; }}