На самом деле, использование синтаксического анализатора XML немного сложнее, чем просто использование модуля XML, поскольку то, что у вас есть, НЕ является правильно сформированным XML. Правильно сформированный XML-файл будет иметь один корень, поэтому все элементы MAIN будут заключены в один элемент.
Однако существует относительно простой способ его подделки, заключающийся в том, чтобы обернуть ваш файл, на который ссылается сущность XML, в соответствующий высокоуровневый элемент.
Кроме того, в данных вашего примера у вас есть элемент LOCATION в первой MAIN, затем элемент LOC во второй MAIN, я предполагаю, что это ошибка cut'n paste.
Вот способ сделать это с XML :: Twig, который будет работать с входным файлом любого размера (включая большой, чтобы уместиться в памяти), и который будет выводиться на стандартный вывод.
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
binmode( STDOUT, ':utf8'); # if your input file is in UTF-8
my $file= shift @ARGV;
# wrap the content of the file in <data>...</data> so it becomes well-formed XML
my $xml= qq{<?xml version="1.0"?>
<!DOCTYPE data [ <!ENTITY file SYSTEM "$file">]>
<data>&file;</data>
};
XML::Twig->new( twig_handlers => { MAIN => \&main },
keep_spaces => 1,
)
->parse( $xml);
exit;
sub main
{ my( $t, $main)= @_;
my $location= $main->field( 'LOCATION');
$main->set_field( VER => get_version( $location));
$main->print;
$main->purge; # if the file is big and you want to free the memory
}
sub get_version
{ my( $location)= @_;
return "new.version.$location"; # the real code might be different!
}
Если ваш входной файл НЕ в UTF-8, вам может потребоваться изменить оболочку, чтобы добавить правильную кодировку в объявление XML. Если в чистом виде используется ASCII, то у вас все хорошо (и при добавлении символов UTF-8 все равно будет работать).
Если вы не хотите использовать XML :: Twig, тот же метод применяется для создания правильного XML, который может быть прочитан XML :: Simple или любым другим модулем, который вы хотите использовать.