3 ms·
Nice. I like the event based/callback based parsing tools for XML a lot. A little more cognitive work up front but much more efficient. A little sad if unsur
by lanstin 2y ago
Nice. I like the event based/callback based parsing tools for XML a lot. A little more cognitive work up front but much more efficient. A little sad if unsurprised that XML is still a thing in 2024, but if you have to read it, use a streaming parser.
- glenjamin 2y agoIf you've ever tried to read data from an XLSX file, you'll find that streaming XML parsing is quite beneficial And the world runs on Excel files.
- IshKebab 2y agoI really hate SAX. Callback based parsing is really unergonomic, and means you always have to code an explicit state machine. You can't use your control flow as implicit state. It's like choosing to use `.then()` instead of `await`. I seriously don't understand why it is so popular in the XML world when pull based parsing is much easier to use and surely just as efficient? Just brain damaged Java design patterns maybe?
- lanstin 2y agoBecause of msgs that are larger than I want to allocate. Explicit state machines forces one to think thru the problem. And it forces the solution to be one pass over the input data. I almost never am forced to use Java so unsure about that reference.
- IshKebab 2y agoPull parsers can deal with arbitrarily large messages too. And they also do one pass over the input data. Yeah if you're unfamiliar, SAX is like this (pseudocode): interface SAXCallbacks { void onBeginToken(string name); void onAttribute(string key, string val); void onText(string text); void onEndToken(string name); } void parse(Reader input, SAXCallbacks yourCallbackImplementations); Whereas pull parsers are like this: enum Token { Begin(string name), Attribute(string key, string val), Text(string text), End(string name), } class PullParser { void open(Reader input); Token next(); } They are much easier to use because you can trivially write a recursive descent parser: void parseThing(parser) { let token = parser.next(); if (token == Begin("foo")) { parseFoo(parser); } else if ... Whereas with SAX you're going to end up with some monstrous hand-coded state machine like class ThingParser { enum State { ParsingThing, ParsingFoo, ParsingFooExpectingAttributes, ParsingFooExpectingEndTag, ... So painful. Honestly it's so obviously the right way to do tokenisation and parsing that I have yet to see another language that even has names for them. They all just use pull parsers. Nobody else does callback-based parsing like SAX because it's obviously ridiculous.