Well As far as I know
XML::Simple allows you to read in XML files as nested hashes of references, which can be very useful if you're only extracting a few values, here is the link for that
And XML:

arser is a SAX based parser. It requires a bit more work than the previous too to set up, as you need to set up event handlers for all of the tags encountered in parsing. As long as you don't need to walk a tree when parsing and can handle all of the tags as they come, this should be quite powerful, and very light on memory.
And finally, if you do need DOM, theres XML:

OM (which is built on top of XML:

arser). I haven't used it myself, but it can be found here:
Here's a very bare-bones example. But it should give you some idea.
Assuming the password file is in this format:
<passwords>
<user>
<name>happy</name>
<pass>sad</pass>
</user>
<user>
<name>dopey</name>
<pass>smart</pass>
</user>
<user>
<name>doc</name>
<pass>patient</pass>
</user>
<user>
<name>sneezy</name>
<pass>chirpy</pass>
</user>
<user>
<name>bashful</name>
<pass>noway</pass>
</user>
</passwords>
Here's the script. Run it with three arguments: password file name, user name and password to check for.
#!/usr/local/bin/perl -w
use XML:

arser;
my ($file, $input_user, $input_pass) = @ARGV;
$xp = new XML:

arser(Handlers => {Start => \&start_handler,
End => \&end_handler,
Char => \&char_handler});
die "can't create XML:

arser object; $!\n"
unless $xp;
my $found = undef;
$xp->parsefile($file);
if ($found) {
print "Welcome, $input_user!\n";
} else {
print "Sorry, $input_user!\n";
}
sub start_handler
{
my ($xp, $elem) = @_;
# print "Start: $elem\n";
if ($elem eq 'name') {
$user_seen = 1;
} elsif ($elem eq 'pass') {
$pass_seen = 1;
}
}
sub end_handler
{
my ($xp, $elem) = @_;
# print "End: $elem\n";
if ($elem eq 'name') {
$user_seen = 0;
} elsif ($elem eq 'pass') {
$pass_seen = 0;
}
}
sub char_handler
{
my ($xp, $str) = @_;
# print " Value: $str\n";
if ($user_seen) {
$curr_user = $str;
} elsif ($pass_seen) {
$curr_pass = $str;
check_pass($curr_user, $curr_pass)
unless ($found);
}
}
sub check_pass
{
my ($user, $pass) = @_;
# print "Checking $user/$pass against $input_user/$input_pass ...\n";
$found = $user eq $input_user and $pass eq $input_pass;
}
Hope that helps.