You might like to try XML::TreePuller. If your sample is a fair representation of your problem then something like the following ought turn the trick for you:
use strict;
use warnings;
use XML::TreePuller;
use XML::Writer;
my $fileA = <<XML;
<doc>
<elem>A</elem>
<elem>B</elem>
<elem>C</elem>
</doc>
XML
my $fileB = <<XML;
<doc>
<elem>1</elem>
<elem>5</elem>
<elem>10</elem>
</doc>
XML
# Open both input files
open my $inA, "<", \$fileA;
open my $inB, "<", \$fileB;
my $readerA = XML::TreePuller->new (IO => $inA);
my $readerB = XML::TreePuller->new (IO => $inB);
my $writer = XML::Writer->new (DATA_MODE => 1);
# Process the files parallel
$readerA->iterate_at('/doc/elem' => 'short');
$readerB->iterate_at('/doc/elem' => 'short');
$writer->startTag ('doc');
while ((my $elmtA = $readerA->next ()) && (my $elmtB = $readerB->next
+())) {
my $nameA = $elmtA->name ();
my $nameB = $elmtB->name ();
next if $nameA ne 'elem';
die "Element mismatch: $nameA ne $nameB\n" if $nameA ne $nameB;
$writer->dataElement ($nameA, $elmtA->text () x $elmtB->text ());
}
$writer->endTag();
close $inA;
close $inB;
Prints:
<doc>
<elem>A</elem>
<elem>BBBBB</elem>
<elem>CCCCCCCCCC</elem>
</doc>
True laziness is hard work