uCalc API Version: 2.1.3-preview.2 Released: 6/17/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.
StopAfter = [int]
Property
Product:
Class:
Gets or sets the maximum number of matches a rule will find and keep, ignoring all subsequent matches for that rule.
Remarks
🎯 Limiting Matches with StopAfter
The @StopAfter property sets a limit on the number of matches a rule can find. Once the specified number of matches has been found, the Transformer stops searching for any more matches for that specific rule. This is an efficient way to limit results when you only need the first few occurrences of a pattern.
The default value is -1 (or the maximum value for an unsigned integer), which signifies no limit.
⚙️ Getter and Setter Behavior
This property functions as both a getter and a setter:
Getter:
var limit = myRule.StopAfter;Returns the current match limit for the rule.Setter:
myRule.StopAfter = 5;orSetStopAfter()method.Sets the match limit. This method supports a fluent interface, returning the Rule object to allow for method chaining.
StopAfter vs. StartAfter vs. Maximum
Choosing the correct property to limit matches is crucial. This table clarifies their distinct behaviors:
| Property | Behavior | Use Case |
|---|---|---|
@StopAfter(n) (This Property) | Keeps the first n matches found and ignores all subsequent ones. | Getting the first few results of a search ("take first n"). |
@StartAfter(n) | Skips the first n matches found and keeps all subsequent ones. | Skipping a known header or preamble ("skip first n"). |
@Maximum(n) | Validates. If more than n matches are found, all matches for this rule are invalidated and discarded. | Enforcing a "max N allowed" structural rule. Fails if the limit is exceeded. |
@GlobalMaximum(n) | Validates globally. If more than n matches are found, all matches for all rules are invalidated. | Failing the entire transform if a critical structural rule is violated. |
You can combine @StartAfter and @StopAfter to retrieve a "page" of results. The @StopAfter limit is applied first during the scan, and then @StartAfter filters that result set. For example, @StartAfter(10).@StopAfter(20) will find the first 20 matches, then discard the first 10, resulting in matches 11 through 20.
💡 Why uCalc? (Comparative Analysis)
In a standard data processing workflow, like using LINQ in C#, you would achieve this imperatively after collecting all results:
// C# LINQ examplevar firstFiveResults = allMatches.Take(5);uCalc's @StopAfter is declarative and can be more performant. You state the limit directly on the rule, and the engine can often stop its search early once the limit is reached, avoiding the work of finding all possible matches in a large document. This makes it a highly efficient tool for processing large-scale text.
Examples
Finds and transforms only the first three occurrences of a pattern, ignoring any subsequent ones.
using uCalcSoftware;
var uc = new uCalc();
var t = uc.NewTransformer();
t.Text = "a b c a d e a f g a h i";
var ruleA = t.FromTo("a", "[A]");
// Only find and transform the first 3 occurrences of 'a'.
ruleA.StopAfter = 3;
Console.WriteLine(t.Transform());
[A] b c [A] d e [A] f g a h i using uCalcSoftware; var uc = new uCalc(); var t = uc.NewTransformer(); t.Text = "a b c a d e a f g a h i"; var ruleA = t.FromTo("a", "[A]"); // Only find and transform the first 3 occurrences of 'a'. ruleA.StopAfter = 3; Console.WriteLine(t.Transform());
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto t = uc.NewTransformer();
t.Text("a b c a d e a f g a h i");
auto ruleA = t.FromTo("a", "[A]");
// Only find and transform the first 3 occurrences of 'a'.
ruleA.StopAfter(3);
cout << t.Transform() << endl;
}
[A] b c [A] d e [A] f g a h i #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto t = uc.NewTransformer(); t.Text("a b c a d e a f g a h i"); auto ruleA = t.FromTo("a", "[A]"); // Only find and transform the first 3 occurrences of 'a'. ruleA.StopAfter(3); cout << t.Transform() << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.NewTransformer()
t.Text = "a b c a d e a f g a h i"
Dim ruleA = t.FromTo("a", "[A]")
'// Only find and transform the first 3 occurrences of 'a'.
ruleA.StopAfter = 3
Console.WriteLine(t.Transform())
End Sub
End Module
[A] b c [A] d e [A] f g a h i Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t = uc.NewTransformer() t.Text = "a b c a d e a f g a h i" Dim ruleA = t.FromTo("a", "[A]") '// Only find and transform the first 3 occurrences of 'a'. ruleA.StopAfter = 3 Console.WriteLine(t.Transform()) End Sub End Module
Processes a log file but stops after finding the first error message to focus on the initial problem.
using uCalcSoftware;
var uc = new uCalc();
var t = uc.NewTransformer();
var logText = "ERROR: Fail 1. INFO: OK. ERROR: Fail 2. ERROR: Fail 3.";
t.Text = logText;
var errorRule = t.Pattern("ERROR: {msg}.");
// Stop after finding the first error to focus on the initial problem.
errorRule.StopAfter = 1;
t.Find();
Console.WriteLine($"First error found: {t.Matches.Text}");
First error found: ERROR: Fail 1. using uCalcSoftware; var uc = new uCalc(); var t = uc.NewTransformer(); var logText = "ERROR: Fail 1. INFO: OK. ERROR: Fail 2. ERROR: Fail 3."; t.Text = logText; var errorRule = t.Pattern("ERROR: {msg}."); // Stop after finding the first error to focus on the initial problem. errorRule.StopAfter = 1; t.Find(); Console.WriteLine($"First error found: {t.Matches.Text}");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto t = uc.NewTransformer();
auto logText = "ERROR: Fail 1. INFO: OK. ERROR: Fail 2. ERROR: Fail 3.";
t.Text(logText);
auto errorRule = t.Pattern("ERROR: {msg}.");
// Stop after finding the first error to focus on the initial problem.
errorRule.StopAfter(1);
t.Find();
cout << "First error found: " << t.Matches().Text() << endl;
}
First error found: ERROR: Fail 1. #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto t = uc.NewTransformer(); auto logText = "ERROR: Fail 1. INFO: OK. ERROR: Fail 2. ERROR: Fail 3."; t.Text(logText); auto errorRule = t.Pattern("ERROR: {msg}."); // Stop after finding the first error to focus on the initial problem. errorRule.StopAfter(1); t.Find(); cout << "First error found: " << t.Matches().Text() << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.NewTransformer()
Dim logText = "ERROR: Fail 1. INFO: OK. ERROR: Fail 2. ERROR: Fail 3."
t.Text = logText
Dim errorRule = t.Pattern("ERROR: {msg}.")
'// Stop after finding the first error to focus on the initial problem.
errorRule.StopAfter = 1
t.Find()
Console.WriteLine($"First error found: {t.Matches.Text}")
End Sub
End Module
First error found: ERROR: Fail 1. Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t = uc.NewTransformer() Dim logText = "ERROR: Fail 1. INFO: OK. ERROR: Fail 2. ERROR: Fail 3." t.Text = logText Dim errorRule = t.Pattern("ERROR: {msg}.") '// Stop after finding the first error to focus on the initial problem. errorRule.StopAfter = 1 t.Find() Console.WriteLine($"First error found: {t.Matches.Text}") End Sub End Module
Internal Test: Combines `@StartAfter` and `@StopAfter` to retrieve a specific 'page' of results (matches 3 through 7).
using uCalcSoftware;
var uc = new uCalc();
var t = uc.NewTransformer();
t.Text = "1 2 3 4 5 6 7 8 9 10 11 12";
var rule = t.Pattern("{@Number}");
// Get a "page" of results: matches 3 through 7.
// The engine will stop finding numbers after the 7th match is found.
// Then, it will skip the first 2 matches from that set.
rule.StartAfter = 2; // Skip first 2
rule.StopAfter = 7; // Find up to 7
t.Find();
Console.WriteLine("Matches found:");
Console.WriteLine(t.Matches.Text);
Matches found:
3
4
5
6
7 using uCalcSoftware; var uc = new uCalc(); var t = uc.NewTransformer(); t.Text = "1 2 3 4 5 6 7 8 9 10 11 12"; var rule = t.Pattern("{@Number}"); // Get a "page" of results: matches 3 through 7. // The engine will stop finding numbers after the 7th match is found. // Then, it will skip the first 2 matches from that set. rule.StartAfter = 2; // Skip first 2 rule.StopAfter = 7; // Find up to 7 t.Find(); Console.WriteLine("Matches found:"); Console.WriteLine(t.Matches.Text);
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto t = uc.NewTransformer();
t.Text("1 2 3 4 5 6 7 8 9 10 11 12");
auto rule = t.Pattern("{@Number}");
// Get a "page" of results: matches 3 through 7.
// The engine will stop finding numbers after the 7th match is found.
// Then, it will skip the first 2 matches from that set.
rule.StartAfter(2); // Skip first 2
rule.StopAfter(7); // Find up to 7
t.Find();
cout << "Matches found:" << endl;
cout << t.Matches().Text() << endl;
}
Matches found:
3
4
5
6
7 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto t = uc.NewTransformer(); t.Text("1 2 3 4 5 6 7 8 9 10 11 12"); auto rule = t.Pattern("{@Number}"); // Get a "page" of results: matches 3 through 7. // The engine will stop finding numbers after the 7th match is found. // Then, it will skip the first 2 matches from that set. rule.StartAfter(2); // Skip first 2 rule.StopAfter(7); // Find up to 7 t.Find(); cout << "Matches found:" << endl; cout << t.Matches().Text() << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.NewTransformer()
t.Text = "1 2 3 4 5 6 7 8 9 10 11 12"
Dim rule = t.Pattern("{@Number}")
'// Get a "page" of results: matches 3 through 7.
'// The engine will stop finding numbers after the 7th match is found.
'// Then, it will skip the first 2 matches from that set.
rule.StartAfter = 2 '// Skip first 2
rule.StopAfter = 7 '// Find up to 7
t.Find()
Console.WriteLine("Matches found:")
Console.WriteLine(t.Matches.Text)
End Sub
End Module
Matches found:
3
4
5
6
7 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim t = uc.NewTransformer() t.Text = "1 2 3 4 5 6 7 8 9 10 11 12" Dim rule = t.Pattern("{@Number}") '// Get a "page" of results: matches 3 through 7. '// The engine will stop finding numbers after the 7th match is found. '// Then, it will skip the first 2 matches from that set. rule.StartAfter = 2 '// Skip first 2 rule.StopAfter = 7 '// Find up to 7 t.Find() Console.WriteLine("Matches found:") Console.WriteLine(t.Matches.Text) End Sub End Module
Rule StartAfter()
using uCalcSoftware;
var uc = new uCalc();
var t = uc.NewTransformer();
var FruitsXML =
"""
""";
var Fruit = t.FromTo("CommonName={@string:name}", "{name}");
// StopAfter()
Fruit.StopAfter = 4;
t.Filter(FruitsXML);
Console.WriteLine($"*** Stop after: {Fruit.StopAfter} ***");
Console.WriteLine(t.Matches.Text);
Fruit.StopAfter = -1; // Resets back to infinity (default) for next example
Console.WriteLine("");
// StartAfter()
Fruit.StartAfter = 6;
t.Filter(FruitsXML);
Console.WriteLine($"*** Start after: {Fruit.StartAfter} ***");
Console.WriteLine(t.Matches.Text);
Fruit.StartAfter = 0; // Resets back to 0 (default) for next example
Console.WriteLine("");
// Both StartAfter() and StopAfter()
Fruit.SetStartAfter(2).SetStopAfter(5);
t.Filter(FruitsXML);
Console.WriteLine($"*** Between {Fruit.StartAfter + 1} and {Fruit.StopAfter} ***");
Console.WriteLine(t.Matches.Text);
Console.WriteLine("");
// All
uc.DefineVariable("x = 1");
Fruit = t.FromTo("CommonName={@string:name}", "{@Eval: x++}. {name}");
t.Filter(FruitsXML);
Console.WriteLine("*** All ***");
Console.WriteLine(t.Matches.Text);
*** Stop after: 4 ***
Apple
Banana
Orange
Grapes
*** Start after: 6 ***
Mango
Blueberry
Rambutan
Salak (Snake Fruit)
Jabuticaba
Watermelon
*** Between 3 and 5 ***
Orange
Grapes
Strawberry
*** All ***
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 t = uc.NewTransformer(); 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> """; var Fruit = t.FromTo("CommonName={@string:name}", "{name}"); // StopAfter() Fruit.StopAfter = 4; t.Filter(FruitsXML); Console.WriteLine($"*** Stop after: {Fruit.StopAfter} ***"); Console.WriteLine(t.Matches.Text); Fruit.StopAfter = -1; // Resets back to infinity (default) for next example Console.WriteLine(""); // StartAfter() Fruit.StartAfter = 6; t.Filter(FruitsXML); Console.WriteLine($"*** Start after: {Fruit.StartAfter} ***"); Console.WriteLine(t.Matches.Text); Fruit.StartAfter = 0; // Resets back to 0 (default) for next example Console.WriteLine(""); // Both StartAfter() and StopAfter() Fruit.SetStartAfter(2).SetStopAfter(5); t.Filter(FruitsXML); Console.WriteLine($"*** Between {Fruit.StartAfter + 1} and {Fruit.StopAfter} ***"); Console.WriteLine(t.Matches.Text); Console.WriteLine(""); // All uc.DefineVariable("x = 1"); Fruit = t.FromTo("CommonName={@string:name}", "{@Eval: x++}. {name}"); t.Filter(FruitsXML); Console.WriteLine("*** All ***"); Console.WriteLine(t.Matches.Text);
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto t = uc.NewTransformer();
auto FruitsXML =
R"(
)";
auto Fruit = t.FromTo("CommonName={@string:name}", "{name}");
// StopAfter()
Fruit.StopAfter(4);
t.Filter(FruitsXML);
cout << "*** Stop after: " << Fruit.StopAfter() << " ***" << endl;
cout << t.Matches().Text() << endl;
Fruit.StopAfter(-1); // Resets back to infinity (default) for next example
cout << "" << endl;
// StartAfter()
Fruit.StartAfter(6);
t.Filter(FruitsXML);
cout << "*** Start after: " << Fruit.StartAfter() << " ***" << endl;
cout << t.Matches().Text() << endl;
Fruit.StartAfter(0); // Resets back to 0 (default) for next example
cout << "" << endl;
// Both StartAfter() and StopAfter()
Fruit.SetStartAfter(2).SetStopAfter(5);
t.Filter(FruitsXML);
cout << "*** Between " << Fruit.StartAfter() + 1 << " and " << Fruit.StopAfter() << " ***" << endl;
cout << t.Matches().Text() << endl;
cout << "" << endl;
// All
uc.DefineVariable("x = 1");
Fruit = t.FromTo("CommonName={@string:name}", "{@Eval: x++}. {name}");
t.Filter(FruitsXML);
cout << "*** All ***" << endl;
cout << t.Matches().Text() << endl;
}
*** Stop after: 4 ***
Apple
Banana
Orange
Grapes
*** Start after: 6 ***
Mango
Blueberry
Rambutan
Salak (Snake Fruit)
Jabuticaba
Watermelon
*** Between 3 and 5 ***
Orange
Grapes
Strawberry
*** All ***
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 t = uc.NewTransformer(); 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> )"; auto Fruit = t.FromTo("CommonName={@string:name}", "{name}"); // StopAfter() Fruit.StopAfter(4); t.Filter(FruitsXML); cout << "*** Stop after: " << Fruit.StopAfter() << " ***" << endl; cout << t.Matches().Text() << endl; Fruit.StopAfter(-1); // Resets back to infinity (default) for next example cout << "" << endl; // StartAfter() Fruit.StartAfter(6); t.Filter(FruitsXML); cout << "*** Start after: " << Fruit.StartAfter() << " ***" << endl; cout << t.Matches().Text() << endl; Fruit.StartAfter(0); // Resets back to 0 (default) for next example cout << "" << endl; // Both StartAfter() and StopAfter() Fruit.SetStartAfter(2).SetStopAfter(5); t.Filter(FruitsXML); cout << "*** Between " << Fruit.StartAfter() + 1 << " and " << Fruit.StopAfter() << " ***" << endl; cout << t.Matches().Text() << endl; cout << "" << endl; // All uc.DefineVariable("x = 1"); Fruit = t.FromTo("CommonName={@string:name}", "{@Eval: x++}. {name}"); t.Filter(FruitsXML); cout << "*** All ***" << endl; cout << t.Matches().Text() << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim t = uc.NewTransformer()
Dim FruitsXML =
"
"
Dim Fruit = t.FromTo("CommonName={@string:name}", "{name}")
'// StopAfter()
Fruit.StopAfter = 4
t.Filter(FruitsXML)
Console.WriteLine($"*** Stop after: {Fruit.StopAfter} ***")
Console.WriteLine(t.Matches.Text)
Fruit.StopAfter = -1 '// Resets back to infinity (default) for next example
Console.WriteLine("")
'// StartAfter()
Fruit.StartAfter = 6
t.Filter(FruitsXML)
Console.WriteLine($"*** Start after: {Fruit.StartAfter} ***")
Console.WriteLine(t.Matches.Text)
Fruit.StartAfter = 0 '// Resets back to 0 (default) for next example
Console.WriteLine("")
'// Both StartAfter() and StopAfter()
Fruit.SetStartAfter(2).SetStopAfter(5)
t.Filter(FruitsXML)
Console.WriteLine($"*** Between {Fruit.StartAfter + 1} and {Fruit.StopAfter} ***")
Console.WriteLine(t.Matches.Text)
Console.WriteLine("")
'// All
uc.DefineVariable("x = 1")
Fruit = t.FromTo("CommonName={@string:name}", "{@Eval: x++}. {name}")
t.Filter(FruitsXML)
Console.WriteLine("*** All ***")
Console.WriteLine(t.Matches.Text)
End Sub
End Module
*** Stop after: 4 ***
Apple
Banana
Orange
Grapes
*** Start after: 6 ***
Mango
Blueberry
Rambutan
Salak (Snake Fruit)
Jabuticaba
Watermelon
*** Between 3 and 5 ***
Orange
Grapes
Strawberry
*** All ***
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 t = uc.NewTransformer() 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> " Dim Fruit = t.FromTo("CommonName={@string:name}", "{name}") '// StopAfter() Fruit.StopAfter = 4 t.Filter(FruitsXML) Console.WriteLine($"*** Stop after: {Fruit.StopAfter} ***") Console.WriteLine(t.Matches.Text) Fruit.StopAfter = -1 '// Resets back to infinity (default) for next example Console.WriteLine("") '// StartAfter() Fruit.StartAfter = 6 t.Filter(FruitsXML) Console.WriteLine($"*** Start after: {Fruit.StartAfter} ***") Console.WriteLine(t.Matches.Text) Fruit.StartAfter = 0 '// Resets back to 0 (default) for next example Console.WriteLine("") '// Both StartAfter() and StopAfter() Fruit.SetStartAfter(2).SetStopAfter(5) t.Filter(FruitsXML) Console.WriteLine($"*** Between {Fruit.StartAfter + 1} and {Fruit.StopAfter} ***") Console.WriteLine(t.Matches.Text) Console.WriteLine("") '// All uc.DefineVariable("x = 1") Fruit = t.FromTo("CommonName={@string:name}", "{@Eval: x++}. {name}") t.Filter(FruitsXML) Console.WriteLine("*** All ***") Console.WriteLine(t.Matches.Text) End Sub End Module