you might want to add an ErrorContext => 1 argument to the parser creation. This will output the line
where the error occured and make it much easier to debug. In this case you would have seen that the parser wasn't parsing anything.
it looks like you have a pretty good idea of the format of the messages, then why don't you use a DTD to check them? You can then use XML::Checker::Parser instead of XML::Parser (it's a plug-in replacement, so all you have to do is use it when you create the parser object, everything else can stay the same. This would give you an extra level of confidence in your data. Just test the performances to make sure it's fast enough for your needs (I have no idea how fast it is).
Here is a simple DTD that would work for the data you showed: