uCalc API Version: 2.1.3-preview.2 Released: 6/16/2026
Warning
uCalc API Preview Release Notice:The documentation describes the intended behavior of the API. The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.
FromTo
Method
Product:
Class:
Defines a token-aware, find-and-replace rule that transforms text matching a pattern.
Syntax
Parameters
Return
Rule
Returns the newly created Rule object, which can be used to further configure its behavior (e.g., setting its active state, case-sensitivity, etc.).
Remarks
FromTo is the cornerstone method of the Transformer engine, used to define a find-and-replace rule. It binds a search pattern to a replacement template, allowing for powerful, token-aware text transformations.
⚙️ How It Works
The method takes two primary arguments: a pattern string and a replacement string.
The Pattern String (
pattern): This string defines what to search for. It uses uCalc's Pattern Syntax which can include:- Literals (Anchors): Exact text that must be present (e.g.,
"ID:"). - Variables (Captures): Placeholders like
{name}or{@Number:val}that capture dynamic content. - Complex Logic: Optional parts (
[]), alternations (|), and other structural directives.
- Literals (Anchors): Exact text that must be present (e.g.,
The Replacement String (
replacement): This string defines how to construct the new text. It can contain:- Literal Text: Characters to be inserted as-is.
- Variable Backreferences: Placeholders like
{name}that re-insert the text captured by the corresponding variable in the pattern. - Pattern Methods: Powerful directives like
{@Eval: ...}to execute code or{!var:default}for conditional logic.
For a complete guide to pattern syntax, see the Patterns section.
🥇 Precedence and Rule Order (LIFO)
A Transformer can have multiple rules. When two or more patterns could potentially match the same text (e.g., "An apple." and "An {item}."), uCalc uses a Last-In, First-Out (LIFO) precedence rule: The most recently defined rule is checked first.
This allows you to define general, catch-all rules first, and then add more specific, higher-precedence rules on top of them.
FromTo vs. Pattern
| Method | Purpose | Replacement Behavior | Use Case |
|---|---|---|---|
FromTo(p, r) | Find and Replace | Uses the provided replacement string r. | Text transformation, data normalization, code generation. |
| Pattern(p) | Find Only | Implicitly uses {@Self} as the replacement (i.e., re-inserts the matched text). | Locating patterns without modifying the source text. |
💡 Why uCalc? (Comparative Analysis)
In many languages, string replacement is handled by regular expressions.
Standard Regex (
Regex.Replace):[csharp]Regex.Replace(input, @"Hello (\w+)", "Greetings, $1");While powerful, regex is purely character-based. It struggles with nested structures, is often difficult to read, and replacement logic is limited to simple backreferences. More complex logic requires using aMatchEvaluatorcallback, which can be verbose.uCalc
FromTo:t.FromTo("Hello {name}", "Greetings, {name}!");uCalc'sFromTooffers significant advantages:- Readability: Patterns use natural language and variables, making them easier to understand and maintain.
- Token-Awareness: uCalc is "safe by default." It understands language structures like quotes and brackets, preventing accidental replacements inside string literals or across mismatched parentheses.
- Embedded Logic: The replacement string can contain conditional logic (
{var: ...}) and execute expressions ({@Eval: ...}) directly, which is far more concise than writing a separate callback function.
This makes FromTo a more robust, readable, and powerful tool for any task involving structured text transformation.
Examples
A simple find-and-replace transformation.
using uCalcSoftware;
var uc = new uCalc();
var t = new uCalc.Transformer();
t.FromTo("Hello {name}", "Greetings, {name}!");
Console.WriteLine(t.Transform("Hello World"));
Greetings, World! using uCalcSoftware; var uc = new uCalc(); var t = new uCalc.Transformer(); t.FromTo("Hello {name}", "Greetings, {name}!"); Console.WriteLine(t.Transform("Hello World"));
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::Transformer t;
t.FromTo("Hello {name}", "Greetings, {name}!");
cout << t.Transform("Hello World") << endl;
}
Greetings, World! #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::Transformer t; t.FromTo("Hello {name}", "Greetings, {name}!"); cout << t.Transform("Hello World") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t As New uCalc.Transformer()
t.FromTo("Hello {name}", "Greetings, {name}!")
Console.WriteLine(t.Transform("Hello World"))
End Sub
End Module
Greetings, World! Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t As New uCalc.Transformer() t.FromTo("Hello {name}", "Greetings, {name}!") Console.WriteLine(t.Transform("Hello World")) End Sub End Module
Using ExpressionTransformer to transform expressions before they are parsed
using uCalcSoftware;
var uc = new uCalc();
var ExprT = uc.ExpressionTransformer; // Transformer used for Eval() and Evaluate()
var p1 = ExprT.FromTo("AddUp({x})", "{x}"); // RewindOnChange False by default
var p2 = ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true);
Console.WriteLine($"p1 RewindOnChange: {p1.RewindOnChange}");
Console.WriteLine($"p2 RewindOnChange: {p2.RewindOnChange}");
Console.WriteLine("");
Console.WriteLine($"Input: AddUp(1,2,3,4)");
Console.WriteLine($"Transform: {ExprT.Transform("AddUp(1,2,3,4)")}");
Console.WriteLine($"Eval: {uc.Eval("AddUp(1,2,3,4)")}");
p1 RewindOnChange: False
p2 RewindOnChange: True
Input: AddUp(1,2,3,4)
Transform: (1 + (2 + (3 + 4)))
Eval: 10 using uCalcSoftware; var uc = new uCalc(); var ExprT = uc.ExpressionTransformer; // Transformer used for Eval() and Evaluate() var p1 = ExprT.FromTo("AddUp({x})", "{x}"); // RewindOnChange False by default var p2 = ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true); Console.WriteLine($"p1 RewindOnChange: {p1.RewindOnChange}"); Console.WriteLine($"p2 RewindOnChange: {p2.RewindOnChange}"); Console.WriteLine(""); Console.WriteLine($"Input: AddUp(1,2,3,4)"); Console.WriteLine($"Transform: {ExprT.Transform("AddUp(1,2,3,4)")}"); Console.WriteLine($"Eval: {uc.Eval("AddUp(1,2,3,4)")}");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
#define tf(IsTrue) ((IsTrue) ? "True" : "False")
int main() {
uCalc uc;
auto ExprT = uc.ExpressionTransformer(); // Transformer used for Eval() and Evaluate()
auto p1 = ExprT.FromTo("AddUp({x})", "{x}"); // RewindOnChange False by default
auto p2 = ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true);
cout << "p1 RewindOnChange: " << tf(p1.RewindOnChange()) << endl;
cout << "p2 RewindOnChange: " << tf(p2.RewindOnChange()) << endl;
cout << "" << endl;
cout << "Input: " << "AddUp(1,2,3,4)" << endl;
cout << "Transform: " << ExprT.Transform("AddUp(1,2,3,4)") << endl;
cout << "Eval: " << uc.Eval("AddUp(1,2,3,4)") << endl;
}
p1 RewindOnChange: False
p2 RewindOnChange: True
Input: AddUp(1,2,3,4)
Transform: (1 + (2 + (3 + 4)))
Eval: 10 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; #define tf(IsTrue) ((IsTrue) ? "True" : "False") int main() { uCalc uc; auto ExprT = uc.ExpressionTransformer(); // Transformer used for Eval() and Evaluate() auto p1 = ExprT.FromTo("AddUp({x})", "{x}"); // RewindOnChange False by default auto p2 = ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true); cout << "p1 RewindOnChange: " << tf(p1.RewindOnChange()) << endl; cout << "p2 RewindOnChange: " << tf(p2.RewindOnChange()) << endl; cout << "" << endl; cout << "Input: " << "AddUp(1,2,3,4)" << endl; cout << "Transform: " << ExprT.Transform("AddUp(1,2,3,4)") << endl; cout << "Eval: " << uc.Eval("AddUp(1,2,3,4)") << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim ExprT = uc.ExpressionTransformer '// Transformer used for Eval() and Evaluate()
Dim p1 = ExprT.FromTo("AddUp({x})", "{x}") '// RewindOnChange False by default
Dim p2 = ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true)
Console.WriteLine($"p1 RewindOnChange: {p1.RewindOnChange}")
Console.WriteLine($"p2 RewindOnChange: {p2.RewindOnChange}")
Console.WriteLine("")
Console.WriteLine($"Input: AddUp(1,2,3,4)")
Console.WriteLine($"Transform: {ExprT.Transform("AddUp(1,2,3,4)")}")
Console.WriteLine($"Eval: {uc.Eval("AddUp(1,2,3,4)")}")
End Sub
End Module
p1 RewindOnChange: False
p2 RewindOnChange: True
Input: AddUp(1,2,3,4)
Transform: (1 + (2 + (3 + 4)))
Eval: 10 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim ExprT = uc.ExpressionTransformer '// Transformer used for Eval() and Evaluate() Dim p1 = ExprT.FromTo("AddUp({x})", "{x}") '// RewindOnChange False by default Dim p2 = ExprT.FromTo("AddUp({x}, {y})", "({x} + AddUp({y}))").SetRewindOnChange(true) Console.WriteLine($"p1 RewindOnChange: {p1.RewindOnChange}") Console.WriteLine($"p2 RewindOnChange: {p2.RewindOnChange}") Console.WriteLine("") Console.WriteLine($"Input: AddUp(1,2,3,4)") Console.WriteLine($"Transform: {ExprT.Transform("AddUp(1,2,3,4)")}") Console.WriteLine($"Eval: {uc.Eval("AddUp(1,2,3,4)")}") End Sub End Module
Maximum, GlobalMaximum
using uCalcSoftware;
var uc = new uCalc();
var FruitsXML =
"""
""";
uc.DefineVariable("x");
var t = uc.NewTransformer();
var FruitsTag = t.FromTo("", "List of fruits");
var Fruit = t.FromTo("CommonName={@string:name}", "{@Eval: x++}. {name}");
uc.Eval("x = 1");
Fruit.Maximum = 10;
t.Filter(FruitsXML);
Console.WriteLine($"Maximum = {Fruit.Maximum}");
Console.WriteLine($"Matches count: {t.Matches.Count()}"); // 1 for FruitsTag occurrence
Console.WriteLine("");
Console.WriteLine(t.Matches);
Console.WriteLine("");
Console.WriteLine("===============");
uc.Eval("x = 1");
Fruit.Maximum = 20;
t.Filter(FruitsXML);
Console.WriteLine($"Maximum = {Fruit.Maximum}");
Console.WriteLine($"Matches count: {t.Matches.Count()}"); // 1 for FruitsTag plus 12 fruits
Console.WriteLine("");
Console.WriteLine(t.Matches);
Console.WriteLine("");
Console.WriteLine("===============");
uc.Eval("x = 1");
Fruit.GlobalMaximum = 10; // Notice "List of fruits" will not show
t.Filter(FruitsXML);
Console.WriteLine($"MaximumAND = {Fruit.GlobalMaximum}");
Console.WriteLine($"Matches count: {t.Matches.Count()}"); // Even FruitsTage won't be counted
Console.WriteLine("");
Console.WriteLine(t.Matches);
Console.WriteLine("===============");
uc.Eval("x = 1");
Fruit.GlobalMaximum = 20;
t.Filter(FruitsXML);
Console.WriteLine($"MaximumAND = {Fruit.GlobalMaximum}");
Console.WriteLine($"Matches count: {t.Matches.Count()}");
Console.WriteLine("");
Console.WriteLine(t.Matches);
Maximum = 10
Matches count: 1
List of fruits
===============
Maximum = 20
Matches count: 13
List of fruits
1. Apple
2. Banana
3. Orange
4. Grapes
5. Strawberry
6. Pineapple
7. Mango
8. Blueberry
9. Rambutan
10. Salak (Snake Fruit)
11. Jabuticaba
12. Watermelon
===============
MaximumAND = 10
Matches count: 0
===============
MaximumAND = 20
Matches count: 13
List of fruits
1. Apple
2. Banana
3. Orange
4. Grapes
5. Strawberry
6. Pineapple
7. Mango
8. Blueberry
9. Rambutan
10. Salak (Snake Fruit)
11. Jabuticaba
12. Watermelon using uCalcSoftware; var uc = new uCalc(); var FruitsXML = """ <Fruits> <Fruit CommonName='Apple' ScientificName='Malus domestica' /> <Fruit CommonName='Banana' ScientificName='Musa acuminata' /> <Fruit CommonName='Orange' ScientificName='Citrus × sinensis' /> <Fruit CommonName='Grapes' ScientificName='Vitis vinifera' /> <Fruit CommonName='Strawberry' ScientificName='Fragaria × ananassa' /> <Fruit CommonName='Pineapple' ScientificName='Ananas comosus' /> <Fruit CommonName='Mango' ScientificName='Mangifera indica' /> <Fruit CommonName='Blueberry' ScientificName='Vaccinium corymbosum' /> <Fruit CommonName='Rambutan' ScientificName='Nephelium lappaceum' /> <Fruit CommonName='Salak (Snake Fruit)' ScientificName='Salacca zalacca' /> <Fruit CommonName='Jabuticaba' ScientificName='Plinia cauliflora' /> <Fruit CommonName='Watermelon' ScientificName='Citrullus lanatus' /> </Fruits> """; uc.DefineVariable("x"); var t = uc.NewTransformer(); var FruitsTag = t.FromTo("<Fruits>", "List of fruits"); var Fruit = t.FromTo("CommonName={@string:name}", "{@Eval: x++}. {name}"); uc.Eval("x = 1"); Fruit.Maximum = 10; t.Filter(FruitsXML); Console.WriteLine($"Maximum = {Fruit.Maximum}"); Console.WriteLine($"Matches count: {t.Matches.Count()}"); // 1 for FruitsTag occurrence Console.WriteLine(""); Console.WriteLine(t.Matches); Console.WriteLine(""); Console.WriteLine("==============="); uc.Eval("x = 1"); Fruit.Maximum = 20; t.Filter(FruitsXML); Console.WriteLine($"Maximum = {Fruit.Maximum}"); Console.WriteLine($"Matches count: {t.Matches.Count()}"); // 1 for FruitsTag plus 12 fruits Console.WriteLine(""); Console.WriteLine(t.Matches); Console.WriteLine(""); Console.WriteLine("==============="); uc.Eval("x = 1"); Fruit.GlobalMaximum = 10; // Notice "List of fruits" will not show t.Filter(FruitsXML); Console.WriteLine($"MaximumAND = {Fruit.GlobalMaximum}"); Console.WriteLine($"Matches count: {t.Matches.Count()}"); // Even FruitsTage won't be counted Console.WriteLine(""); Console.WriteLine(t.Matches); Console.WriteLine("==============="); uc.Eval("x = 1"); Fruit.GlobalMaximum = 20; t.Filter(FruitsXML); Console.WriteLine($"MaximumAND = {Fruit.GlobalMaximum}"); Console.WriteLine($"Matches count: {t.Matches.Count()}"); Console.WriteLine(""); Console.WriteLine(t.Matches);
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto FruitsXML =
R"(
)";
uc.DefineVariable("x");
auto t = uc.NewTransformer();
auto FruitsTag = t.FromTo("", "List of fruits");
auto Fruit = t.FromTo("CommonName={@string:name}", "{@Eval: x++}. {name}");
uc.Eval("x = 1");
Fruit.Maximum(10);
t.Filter(FruitsXML);
cout << "Maximum = " << Fruit.Maximum() << endl;
cout << "Matches count: " << t.Matches().Count() << endl; // 1 for FruitsTag occurrence
cout << "" << endl;
cout << t.Matches() << endl;
cout << "" << endl;
cout << "===============" << endl;
uc.Eval("x = 1");
Fruit.Maximum(20);
t.Filter(FruitsXML);
cout << "Maximum = " << Fruit.Maximum() << endl;
cout << "Matches count: " << t.Matches().Count() << endl; // 1 for FruitsTag plus 12 fruits
cout << "" << endl;
cout << t.Matches() << endl;
cout << "" << endl;
cout << "===============" << endl;
uc.Eval("x = 1");
Fruit.GlobalMaximum(10); // Notice "List of fruits" will not show
t.Filter(FruitsXML);
cout << "MaximumAND = " << Fruit.GlobalMaximum() << endl;
cout << "Matches count: " << t.Matches().Count() << endl; // Even FruitsTage won't be counted
cout << "" << endl;
cout << t.Matches() << endl;
cout << "===============" << endl;
uc.Eval("x = 1");
Fruit.GlobalMaximum(20);
t.Filter(FruitsXML);
cout << "MaximumAND = " << Fruit.GlobalMaximum() << endl;
cout << "Matches count: " << t.Matches().Count() << endl;
cout << "" << endl;
cout << t.Matches() << endl;
}
Maximum = 10
Matches count: 1
List of fruits
===============
Maximum = 20
Matches count: 13
List of fruits
1. Apple
2. Banana
3. Orange
4. Grapes
5. Strawberry
6. Pineapple
7. Mango
8. Blueberry
9. Rambutan
10. Salak (Snake Fruit)
11. Jabuticaba
12. Watermelon
===============
MaximumAND = 10
Matches count: 0
===============
MaximumAND = 20
Matches count: 13
List of fruits
1. Apple
2. Banana
3. Orange
4. Grapes
5. Strawberry
6. Pineapple
7. Mango
8. Blueberry
9. Rambutan
10. Salak (Snake Fruit)
11. Jabuticaba
12. Watermelon #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto FruitsXML = R"( <Fruits> <Fruit CommonName='Apple' ScientificName='Malus domestica' /> <Fruit CommonName='Banana' ScientificName='Musa acuminata' /> <Fruit CommonName='Orange' ScientificName='Citrus × sinensis' /> <Fruit CommonName='Grapes' ScientificName='Vitis vinifera' /> <Fruit CommonName='Strawberry' ScientificName='Fragaria × ananassa' /> <Fruit CommonName='Pineapple' ScientificName='Ananas comosus' /> <Fruit CommonName='Mango' ScientificName='Mangifera indica' /> <Fruit CommonName='Blueberry' ScientificName='Vaccinium corymbosum' /> <Fruit CommonName='Rambutan' ScientificName='Nephelium lappaceum' /> <Fruit CommonName='Salak (Snake Fruit)' ScientificName='Salacca zalacca' /> <Fruit CommonName='Jabuticaba' ScientificName='Plinia cauliflora' /> <Fruit CommonName='Watermelon' ScientificName='Citrullus lanatus' /> </Fruits> )"; uc.DefineVariable("x"); auto t = uc.NewTransformer(); auto FruitsTag = t.FromTo("<Fruits>", "List of fruits"); auto Fruit = t.FromTo("CommonName={@string:name}", "{@Eval: x++}. {name}"); uc.Eval("x = 1"); Fruit.Maximum(10); t.Filter(FruitsXML); cout << "Maximum = " << Fruit.Maximum() << endl; cout << "Matches count: " << t.Matches().Count() << endl; // 1 for FruitsTag occurrence cout << "" << endl; cout << t.Matches() << endl; cout << "" << endl; cout << "===============" << endl; uc.Eval("x = 1"); Fruit.Maximum(20); t.Filter(FruitsXML); cout << "Maximum = " << Fruit.Maximum() << endl; cout << "Matches count: " << t.Matches().Count() << endl; // 1 for FruitsTag plus 12 fruits cout << "" << endl; cout << t.Matches() << endl; cout << "" << endl; cout << "===============" << endl; uc.Eval("x = 1"); Fruit.GlobalMaximum(10); // Notice "List of fruits" will not show t.Filter(FruitsXML); cout << "MaximumAND = " << Fruit.GlobalMaximum() << endl; cout << "Matches count: " << t.Matches().Count() << endl; // Even FruitsTage won't be counted cout << "" << endl; cout << t.Matches() << endl; cout << "===============" << endl; uc.Eval("x = 1"); Fruit.GlobalMaximum(20); t.Filter(FruitsXML); cout << "MaximumAND = " << Fruit.GlobalMaximum() << endl; cout << "Matches count: " << t.Matches().Count() << endl; cout << "" << endl; cout << t.Matches() << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim FruitsXML =
"
"
uc.DefineVariable("x")
Dim t = uc.NewTransformer()
Dim FruitsTag = t.FromTo("", "List of fruits")
Dim Fruit = t.FromTo("CommonName={@string:name}", "{@Eval: x++}. {name}")
uc.Eval("x = 1")
Fruit.Maximum = 10
t.Filter(FruitsXML)
Console.WriteLine($"Maximum = {Fruit.Maximum}")
Console.WriteLine($"Matches count: {t.Matches.Count()}") '// 1 for FruitsTag occurrence
Console.WriteLine("")
Console.WriteLine(t.Matches)
Console.WriteLine("")
Console.WriteLine("===============")
uc.Eval("x = 1")
Fruit.Maximum = 20
t.Filter(FruitsXML)
Console.WriteLine($"Maximum = {Fruit.Maximum}")
Console.WriteLine($"Matches count: {t.Matches.Count()}") '// 1 for FruitsTag plus 12 fruits
Console.WriteLine("")
Console.WriteLine(t.Matches)
Console.WriteLine("")
Console.WriteLine("===============")
uc.Eval("x = 1")
Fruit.GlobalMaximum = 10 '// Notice "List of fruits" will not show
t.Filter(FruitsXML)
Console.WriteLine($"MaximumAND = {Fruit.GlobalMaximum}")
Console.WriteLine($"Matches count: {t.Matches.Count()}") '// Even FruitsTage won't be counted
Console.WriteLine("")
Console.WriteLine(t.Matches)
Console.WriteLine("===============")
uc.Eval("x = 1")
Fruit.GlobalMaximum = 20
t.Filter(FruitsXML)
Console.WriteLine($"MaximumAND = {Fruit.GlobalMaximum}")
Console.WriteLine($"Matches count: {t.Matches.Count()}")
Console.WriteLine("")
Console.WriteLine(t.Matches)
End Sub
End Module
Maximum = 10
Matches count: 1
List of fruits
===============
Maximum = 20
Matches count: 13
List of fruits
1. Apple
2. Banana
3. Orange
4. Grapes
5. Strawberry
6. Pineapple
7. Mango
8. Blueberry
9. Rambutan
10. Salak (Snake Fruit)
11. Jabuticaba
12. Watermelon
===============
MaximumAND = 10
Matches count: 0
===============
MaximumAND = 20
Matches count: 13
List of fruits
1. Apple
2. Banana
3. Orange
4. Grapes
5. Strawberry
6. Pineapple
7. Mango
8. Blueberry
9. Rambutan
10. Salak (Snake Fruit)
11. Jabuticaba
12. Watermelon Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim FruitsXML = " <Fruits> <Fruit CommonName='Apple' ScientificName='Malus domestica' /> <Fruit CommonName='Banana' ScientificName='Musa acuminata' /> <Fruit CommonName='Orange' ScientificName='Citrus × sinensis' /> <Fruit CommonName='Grapes' ScientificName='Vitis vinifera' /> <Fruit CommonName='Strawberry' ScientificName='Fragaria × ananassa' /> <Fruit CommonName='Pineapple' ScientificName='Ananas comosus' /> <Fruit CommonName='Mango' ScientificName='Mangifera indica' /> <Fruit CommonName='Blueberry' ScientificName='Vaccinium corymbosum' /> <Fruit CommonName='Rambutan' ScientificName='Nephelium lappaceum' /> <Fruit CommonName='Salak (Snake Fruit)' ScientificName='Salacca zalacca' /> <Fruit CommonName='Jabuticaba' ScientificName='Plinia cauliflora' /> <Fruit CommonName='Watermelon' ScientificName='Citrullus lanatus' /> </Fruits> " uc.DefineVariable("x") Dim t = uc.NewTransformer() Dim FruitsTag = t.FromTo("<Fruits>", "List of fruits") Dim Fruit = t.FromTo("CommonName={@string:name}", "{@Eval: x++}. {name}") uc.Eval("x = 1") Fruit.Maximum = 10 t.Filter(FruitsXML) Console.WriteLine($"Maximum = {Fruit.Maximum}") Console.WriteLine($"Matches count: {t.Matches.Count()}") '// 1 for FruitsTag occurrence Console.WriteLine("") Console.WriteLine(t.Matches) Console.WriteLine("") Console.WriteLine("===============") uc.Eval("x = 1") Fruit.Maximum = 20 t.Filter(FruitsXML) Console.WriteLine($"Maximum = {Fruit.Maximum}") Console.WriteLine($"Matches count: {t.Matches.Count()}") '// 1 for FruitsTag plus 12 fruits Console.WriteLine("") Console.WriteLine(t.Matches) Console.WriteLine("") Console.WriteLine("===============") uc.Eval("x = 1") Fruit.GlobalMaximum = 10 '// Notice "List of fruits" will not show t.Filter(FruitsXML) Console.WriteLine($"MaximumAND = {Fruit.GlobalMaximum}") Console.WriteLine($"Matches count: {t.Matches.Count()}") '// Even FruitsTage won't be counted Console.WriteLine("") Console.WriteLine(t.Matches) Console.WriteLine("===============") uc.Eval("x = 1") Fruit.GlobalMaximum = 20 t.Filter(FruitsXML) Console.WriteLine($"MaximumAND = {Fruit.GlobalMaximum}") Console.WriteLine($"Matches count: {t.Matches.Count()}") Console.WriteLine("") Console.WriteLine(t.Matches) End Sub End Module