Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
XmlScriptDocument.cs
1using System.Collections.Generic;
2using System.Threading.Tasks;
3using System.Xml;
7
9{
14 {
15 private readonly XmlScriptProcessingInstruction[] processingInstructions;
16 private XmlScriptElement root;
17 private readonly int nrInstructions;
18 private bool isAsync;
19
30 : base(Start, Length, Expression)
31 {
32 this.root = Root;
33 this.root?.SetParent(this);
34
35 this.processingInstructions = ProcessingInstructions;
36 this.processingInstructions?.SetParent(this);
37
38 this.nrInstructions = ProcessingInstructions.Length;
39
40 this.CalcIsAsync();
41 }
42
43 private void CalcIsAsync()
44 {
45 this.isAsync = this.root?.IsAsynchronous ?? false;
46 if (this.isAsync)
47 return;
48
49 for (int i = 0; i < this.nrInstructions; i++)
50 {
51 if (this.processingInstructions[i]?.IsAsynchronous ?? false)
52 {
53 this.isAsync = true;
54 break;
55 }
56 }
57 }
58
59
63 public XmlScriptElement Root => this.root;
64
69 public override bool IsAsynchronous => this.isAsync;
70
78 public override bool ForAllChildNodes(ScriptNodeEventHandler Callback, object State, SearchMethod Order)
79 {
80 int i, c = this.processingInstructions.Length;
81
82 if (Order == SearchMethod.DepthFirst)
83 {
84 for (i = 0; i < c; i++)
85 {
86 if (!this.processingInstructions[i].ForAllChildNodes(Callback, State, Order))
87 return false;
88 }
89
90 if (!this.root.ForAllChildNodes(Callback, State, Order))
91 return false;
92 }
93
94 ScriptNode NewNode;
95 bool RecalcIsAsync = false;
96 bool b;
97
98 for (i = 0; i < this.nrInstructions; i++)
99 {
100 b = !Callback(this.processingInstructions[i], out NewNode, State);
101 if (!(NewNode is null) && NewNode is XmlScriptProcessingInstruction Instruction)
102 {
103 this.processingInstructions[i] = Instruction;
104 Instruction.SetParent(this);
105
106 RecalcIsAsync = true;
107 }
108
109 if (b || (Order == SearchMethod.TreeOrder && !this.processingInstructions[i].ForAllChildNodes(Callback, State, Order)))
110 {
111 if (RecalcIsAsync)
112 this.CalcIsAsync();
113
114 return false;
115 }
116 }
117
118 if (!(this.root is null))
119 {
120 b = !Callback(this.root, out NewNode, State);
121 if (!(NewNode is null) && NewNode is XmlScriptElement NewRoot)
122 {
123 this.root = NewRoot;
124 this.root.SetParent(this);
125
126 RecalcIsAsync = true;
127 }
128
129 if (b || (Order == SearchMethod.TreeOrder && !this.root.ForAllChildNodes(Callback, State, Order)))
130 {
131 if (RecalcIsAsync)
132 this.CalcIsAsync();
133
134 return false;
135 }
136 }
137
138 if (Order == SearchMethod.BreadthFirst)
139 {
140 for (i = 0; i < c; i++)
141 {
142 if (!this.processingInstructions[i].ForAllChildNodes(Callback, State, Order))
143 return false;
144 }
145
146 if (!this.root.ForAllChildNodes(Callback, State, Order))
147 return false;
148 }
149
150 return true;
151 }
152
159 {
160 XmlDocument Doc = new XmlDocument()
161 {
162 PreserveWhitespace = true
163 };
164
165 this.Build(Doc, null, Variables);
166
167 return new ObjectValue(Doc);
168 }
169
175 public override async Task<IElement> EvaluateAsync(Variables Variables)
176 {
177 if (!this.isAsync)
178 return this.Evaluate(Variables);
179
180 XmlDocument Doc = new XmlDocument()
181 {
182 PreserveWhitespace = true
183 };
184
185 await this.BuildAsync(Doc, null, Variables);
186
187 return new ObjectValue(Doc);
188 }
189
196 internal override void Build(XmlDocument Document, XmlElement Parent, Variables Variables)
197 {
198 foreach (XmlScriptProcessingInstruction PI in this.processingInstructions)
199 PI.Build(Document, Parent, Variables);
200
201 this.root?.Build(Document, Parent, Variables);
202 }
203
210 internal override async Task BuildAsync(XmlDocument Document, XmlElement Parent, Variables Variables)
211 {
212 foreach (XmlScriptProcessingInstruction PI in this.processingInstructions)
213 await PI.BuildAsync(Document, Parent, Variables);
214
215 if (!(this.root is null))
216 await this.root.BuildAsync(Document, Parent, Variables);
217 }
218
225 public override PatternMatchResult PatternMatch(IElement CheckAgainst, Dictionary<string, IElement> AlreadyFound)
226 {
227 if (!(CheckAgainst?.AssociatedObjectValue is XmlNode Node))
228 return PatternMatchResult.NoMatch;
229
230 return this.PatternMatch(Node, AlreadyFound);
231 }
232
239 public override PatternMatchResult PatternMatch(XmlNode CheckAgainst, Dictionary<string, IElement> AlreadyFound)
240 {
241 System.Collections.IEnumerable Nodes;
242
243 if (CheckAgainst is XmlDocument Doc)
244 Nodes = Doc.ChildNodes;
245 else if (CheckAgainst is XmlElement E)
246 Nodes = new XmlElement[] { E };
247 else
248 return PatternMatchResult.NoMatch;
249
250 int PiIndex = 0;
251 bool RootMatched = false;
252 PatternMatchResult Result;
253
254 foreach (XmlNode N in Nodes)
255 {
256 if (N is XmlElement)
257 {
258 if (RootMatched || this.root is null)
259 return PatternMatchResult.NoMatch;
260
261 if ((Result = this.root.PatternMatch(N, AlreadyFound)) != PatternMatchResult.Match)
262 return Result;
263
264 RootMatched = true;
265 }
266 else if (N is XmlDeclaration)
267 {
268 if (PiIndex < this.processingInstructions.Length &&
269 (Result = this.processingInstructions[PiIndex++].PatternMatch(N, AlreadyFound)) != PatternMatchResult.Match)
270 {
271 return Result;
272 }
273 }
274 else if (N is XmlProcessingInstruction)
275 {
276 if (PiIndex >= this.processingInstructions.Length)
277 return PatternMatchResult.NoMatch;
278 else if ((Result = this.processingInstructions[PiIndex++].PatternMatch(N, AlreadyFound)) != PatternMatchResult.Match)
279 return Result;
280 }
281 else if (N is XmlComment || N is XmlSignificantWhitespace || N is XmlWhitespace)
282 continue;
283 else
284 return PatternMatchResult.NoMatch;
285 }
286
287 if (!RootMatched && !(this.root is null))
288 return PatternMatchResult.NoMatch;
289
290 if (PiIndex < this.processingInstructions.Length)
291 return PatternMatchResult.NoMatch;
292
293 return PatternMatchResult.Match;
294 }
295
301 public override bool IsApplicable(XmlNode CheckAgainst)
302 {
303 return (CheckAgainst is XmlDocument);
304 }
305
306 }
307}
Class managing a script expression.
Definition: Expression.cs:39
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
int Length
Length of expression covered by node.
Definition: ScriptNode.cs:101
ScriptNode Parent
Parent node.
Definition: ScriptNode.cs:126
int Start
Start position in script expression.
Definition: ScriptNode.cs:92
void SetParent(ScriptNode Parent)
Sets the parent node. Can only be used when expression is being parsed.
Definition: ScriptNode.cs:132
Collection of variables.
Definition: Variables.cs:25
Represents an script-based XML document.
override async Task< IElement > EvaluateAsync(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection.
XmlScriptElement Root
Root element.
XmlScriptDocument(XmlScriptElement Root, XmlScriptProcessingInstruction[] ProcessingInstructions, int Start, int Length, Expression Expression)
Represents an script-based XML document.
override bool IsApplicable(XmlNode CheckAgainst)
If the node is applicable in pattern matching against CheckAgainst .
override bool ForAllChildNodes(ScriptNodeEventHandler Callback, object State, SearchMethod Order)
Calls the callback method for all child nodes.
override IElement Evaluate(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection.
override PatternMatchResult PatternMatch(IElement CheckAgainst, Dictionary< string, IElement > AlreadyFound)
Performs a pattern match operation.
override PatternMatchResult PatternMatch(XmlNode CheckAgainst, Dictionary< string, IElement > AlreadyFound)
Performs a pattern match operation.
override bool IsAsynchronous
If the node (or its decendants) include asynchronous evaluation. Asynchronous nodes should be evaluat...
override bool IsAsynchronous
If the node (or its decendants) include asynchronous evaluation. Asynchronous nodes should be evaluat...
override PatternMatchResult PatternMatch(XmlNode CheckAgainst, Dictionary< string, IElement > AlreadyFound)
Performs a pattern match operation.
override bool ForAllChildNodes(ScriptNodeEventHandler Callback, object State, SearchMethod Order)
Calls the callback method for all child nodes.
Base class for all XML Script nodes in a parsed script tree.
Basic interface for all types of elements.
Definition: IElement.cs:20
delegate bool ScriptNodeEventHandler(ScriptNode Node, out ScriptNode NewNode, object State)
Delegate for ScriptNode callback methods.
PatternMatchResult
Status result of a pattern matching operation.
Definition: ScriptNode.cs:17
SearchMethod
Method to traverse the expression structure
Definition: ScriptNode.cs:38