in reply to parsing reserved chars with xml::simple

Your problem, as several people have pointed out, is that the thing that's handing you data isn't handing you XML. Instead, it's almost XML. Well, if I pass my machine binary code that is almost a valid program, but not quite, I get a core dump (as I should). If someone is contractually required to be handing you XML, you should bring this up with your manager. For the record, what the people on the other end should be sending you is:
<?xml version="1.0" encoding="UTF-8"?> <TRANSACTION> <FIELDS> <FIELD KEY="user">name</FIELD> <FIELD KEY="password">pass&amp;word</FIELD> <FIELD KEY="operation_type">do_what</FIELD> </FIELDS> </TRANSACTION>
Instead of &amp;, they could also say &#38; or &#x16;. The point is, their process isn't generating XML. For another example, consider that print XMLout({password => ['pass&word']}); produces:
<opt> <password>pass&amp;word</password> </opt>
Assuming that the other end doesn't fix this, there are at least two ways to try to fix this in your code. One, as another poster alluded to, is to wrap the offending section in CDATA. If you happen to know that the process generating this almost-XML-but-not-quite always puts its garbage inside FIELD tags, and that the open and close FIELD is always on the same line, you could do this before sending your output to the xml processor:
$xmltext =~ s{(<FIELD .*?>)(.*)(</FIELD)}{$1<![CDATA[$2]]>$3}
Of course, this has the disadvantage that if your source ever starts to send XML documents that are in fact XML documents, with everything escaped as it should be, then your code will now read it incorrectly.

Since your input isn't XML, you could also try parsing it by something that's not an XML parser, as suggested earlier by the reference to the wonderful article The Wrong Parser for the Right Reasons. For example, stealing copiously from that article, and using the HTML::Stream class for output, here's something that turns that particular bad non-XML into proper XML. This code simply assumes that anything between <FIELD> and </FIELD> was meant to be plain text, and not pieces of tags, or whatever. I've taken the liberty of adding several messed-up password examples:

#!perl use HTML::Parser; use HTML::Stream; # see HTML::Stream documentation for how to output to a scalar $output = new HTML::Stream \*STDOUT; # inside FIELDs, ignore stuff that looks like tags $insidefield = 0; my $p = HTML::Parser->new ( xml_mode => 1, start_h => [sub { my ($tagname, $attr,$text) = @_; if ($insidefield) {$output->text($text);} else {$output->tag($tagname, %$attr);} if ($tagname eq 'FIELD') {$insidefield = 1;} }, "tagname, attr,text"], text_h => [sub { my ($text) = @_; $output->text($text); }, "dtext"], end_h => [sub { my ($tagname, $text) = @_; if ($tagname eq 'FIELD') {$insidefield = 0;} if ($insidefield) {$output->text($text);} else {$output->tag("_$tagname");} }, "tagname, text"], ); $p->parse_file(\*DATA); __END__ <TRANSACTION> <FIELDS> <FIELD KEY="user">name</FIELD> <FIELD KEY="passwordlt">pass<word</FIELD> <FIELD KEY="passwordamp">pass&word</FIELD> <FIELD KEY="passwordgt">pass>word</FIELD> <FIELD KEY="passwordalmost">pass&ampword</FIELD> <FIELD KEY="passwordampcorrect">pass&amp;word</FIELD> <FIELD KEY="passwordtag">pa<ssw>ord</FIELD> <FIELD KEY="operation_type">do_what</FIELD> </FIELDS> </TRANSACTION>
This code produces:
<TRANSACTION> <FIELDS> <FIELD KEY="user">name</FIELD> <FIELD KEY="passwordlt">pass&lt;word</FIELD> <FIELD KEY="passwordamp">pass&amp;word</FIELD> <FIELD KEY="passwordgt">pass&gt;word</FIELD> <FIELD KEY="passwordalmost">pass&amp;ampword</FIELD> <FIELD KEY="passwordampcorrect">pass&amp;word</FIELD> <FIELD KEY="passwordtag">pa&lt;ssw&gt;ord</FIELD> <FIELD KEY="operation_type">do_what</FIELD> </FIELDS> </TRANSACTION>
Note that passwordampcorrect is passed through unchanged. This is because that text was already valid. (It had everything already properly escaped - so that if your data supplier fixes their stuff, you'll still be ok) If you want to massage that content too, just change the "dtext" to "text". Also, if you're not worried about downright pathological text such as the passwordtag example, the program above can be simplified substantially by removing the bits that change the $insidefield variable and replacing the if ($insidefield) bits with the else block.

Note that this program still fails to make heads or tails of things if someone wants to make "</FIELD>" their password. When that happens, you need to really start beating on the source of your data to send you valid XML.