Ok, the numbers were indeed so bad that some action was required

Several optimizations are now in place:
- avoid usage of temporary dynamic strings in XML scanner
- directly use dynamic strings from XML scanner to set names, values, ... of XML objects
- experimental: use string pool to avoid allocation of many dynamic strings with same content
For my test, this makes parsing a large XML document about 3x faster in average, so the current WinAos version should outperform the old version. Also, the slow initial run disappeared so the results are more consistent now.
Note:
For large XML documents as the one you mentioned that have a regular structure, it makes a lot of sense to enable the usage of a string pool. This means that strings will be re-used if their content is the same instead of allocating a new dynamic string for every content.
For example, even if you just use 10 different element names in the whole document, the previous XML parser would have allocated a new dynamic string for any element instance. So if you had one million elements sharing the same 10 names, one million dynamic string were allocated.
To enable the string pool: XMLScanner.Scanner.SetStringPooling({0..31}). This will pool all kind of strings (also data).
Important: Any String returned by any XML.* object must not be mutated! So never change such a string when you have a reference to it. It is fine, however, to set a name/value/whatever to a new(!) dynamic string.