Hi, Jeff.
Sorry for the delay.
I think this looks good in principle, my suggestion would be to do a deeper cleanup first. Especially for 'empty_element' field.
Right now it's used for things that are not elements, with name suggesting otherwise. Using 'struct element' for it is also misleading for the same reason.
Maybe we can keep is as is, and use strictly for empty elements, because it's used together with element stack. Then we could add another structure, without defined type for example as a part of reader struct, to hold temporary data for "current" node - strings and position.