Make the XmlGrammar event based so that it can be easily subclassed.

- The performance characteristics of the new implementation is identical to the previous one.
- All tests still pass.