xml_string0: outline the inner loop body functionality
The motivation for this change is to move towards consolidating XML-escaping
functionality. The introduced function, `xml_core`, is intended to be usable by
`xml_url_string` and other Graphviz XML escaping functions in future.
This aim of consolidation hopefully also explains why this change looks more
complicated than might be expected. It is intended to be functionally a no-op.
But `xml_core` takes a generalized callback and state because it is imagined a
future caller may want to pass in, e.g. `gvputs` as their target sink for
XML-escaped data. That is, future changes may side step the static buffer usage
and allocation that happens in `xml_string0` and instead pump bytes directly
into a final target file.