У меня очень длинный xml, и я хочу обновить значение атрибута одного из тегов, который очень глубоко вложен, поэтому не хотите идти узлом по узлу. Также структура не совпадает по целевому узлу всегда, как можно увидеть ниже: Input XML является:Изменение значения атрибута тега xml с помощью perl
<Re>
<Co Class="Parameter" ID="CSCP001" Status="Available">
<FileSpec URL="c://mine/testfiles/wln/c.txt"/>
<CoOp Operation="Tag" SourceCS="RGB" SourceObjects="All">
<FileSpec Resource="SourceProfile" URL="c://mine/testfiles/wln/d.txt"/>
</CoOp>
</Co>
<Ru Class="Parameter" ID="IDR002" PartIDKeys="Run" Status="Available">
<Ru EndOfDocument="true" Pages="0" Run="1" RunTag="First">
<La>
<FileSpec URL="c://mine/testfiles/wln/e.txt"/>
</La>
</Ru>
</Ru>
</Re>
и я хочу иметь вывода XML, как
<Re>
<Co Class="Parameter" ID="CSCP001" Status="Available">
<FileSpec URL="d://yours/wln/c.txt"/>
<CoOp Operation="Tag" SourceCS="RGB" SourceObjects="All">
<FileSpec Resource="SourceProfile" URL="d://yours/wln/d.txt"/>
</CoOp>
</Co>
<Ru Class="Parameter" ID="IDR002" PartIDKeys="Run" Status="Available">
<Ru EndOfDocument="true" Pages="0" Run="1" RunTag="First">
<La>
<FileSpec URL="d://yours/wln/e.txt"/>
</La>
</Ru>
</Ru>
</Re>
Я попытался с помощью XML простой, xmllib но не в состоянии сделать необходимое. Я новичок в программировании perl.
use XML::LibXML qw();
use XML::LibXML;
use Data::Dumper;
my $xml = "a.txt";
my $xpath_expression = 'FileSpec';
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($xml) or warn "Could not";
my $parser1 = XML::LibXML::Element->new($xml);
for my $FileSpec1 ($doc->getElementsByTagName('FileSpec'))
{
print $FileSpec1;
my $xpath = '$FileSpec1/@URL';
my ($attr) = $doc->findnodes($xpath);
$attr->setValue('dfdsa');
my ($URL1) = $FileSpec1->findvalue('@URL');
print $URL1;
}
Я попытался использовать $ node-> setAttribute ($ aname, $ avalue); но это бросает исключения. Пожалуйста посоветуй.
если вы замените '' twig_handlers' на twig_roots', добавьте '$ _-> flush' в конце обработчика и добавить 'twig_print_outside_roots => 1' для конструктора, который становится' my $ twig = XML :: Twig-> new (twig_roots => {'FileSpec' => sub {$ _-> set_att ('URL', $ new_url) , $ _-. flush;}}, twig_print_outside_roots => 1, pretty_print => 'indented',) ', тогда файл будет анализироваться, но не полностью загружен в память, поэтому объем памяти должен быть минимальным. – mirod
@mirod: Спасибо. Я не привык использовать 'twig_roots()', но это вариант, который нужно учитывать. Я добавил его в ответ, чтобы его было легче читать, но вы должны создать свой собственный ответ. Посоветуйте мне в этом случае удалить его. – Birei
с использованием 'twig_roots' не требуется, если файл действительно большой и не помещается в память. В большинстве случаев вы отвечаете хорошо. Я просто прокомментировал это из-за «очень длинного XML» в вопросе. – mirod