I haven't done a lot of work with XML containing "invalid" characters before, but
it seems to me you have two completely separate problems here.
First, there are characters in your data that you may not want. You should decide what those are and how you want to remove/replace them independent of any XML restrictions. For instance, you may have things like x^H_y^H_z^H_
where you decide you want to strip both the backspace and the following character. Or it's possible that you in fact don't want to adjust your data but feel forced to by the need to represent it in XML.
Update: I've preserved the following paragraphs for posterity, but they are based on a misunderstanding: I thought you could include any character in XML data so long as you encoded it properly, but it seems there are some characters that are outright verboten,
even encoded? XML::LibXML strips these out (at least the current version does so), except for the nul character, which it treats as the end of the string, discarding it and anything that follows :(
Second, you may have characters in your data that you've kept that need encoding in XML. Ideally, whatever XML module you use would do this for you, but if it isn't, you should be able to do it manually, with something like:
use HTML::Entities "encode_entities_numeric";
$encoded_string = encode_entities_numeric( $string, "\x00-\x08\x0B\x0C\x0E-\x19");
But that's really just a stopgap measure. Use a proper XML module; see for instance this answer.