Невозможно добавить новый тег с помощью модуля XML :: Twig в perl - PullRequest
0 голосов
/ 14 апреля 2020

Я пытаюсь проверить наличие тега или добавить его, если он недоступен. В этом случае я пытаюсь добавить новый тег: <testProd>true</testProd> внутри <characteristics> тег.

Мой xml: -

<?xml version="1.0"?>
<test testProp="false">
<Env>
  <log>XM</log>
  <uvmversion>1.2</uvmversion>
</Env>
<classes>
  <class instances="1" name="total"/>
</classes>
<characteristics>
   <pctest>true</pctest>
</characteristics>
</test>

Сценарий: -

use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig->new(
 pretty_print => 'indented',
 twig_handlers => {
         testProd => \&Check_tag,
         characteristics => sub {
                              $_->insert_new_elt( last_child => 'supportsMVV' )->set_text('true'); 'true' );
    },
},
);

$twig->parsefile('applying.xml');
$twig->print;    

sub Check_tag{
 my $item = $_->tag;
 if (defined $item) {
  print "'testProd' tag is already defined in given xml file.\n ";
 exit;
}
}

Не уверен, что не так с моим скриптом. Я могу напечатать вывод xml, используя оператор '$twig->print;', который потребовал изменений, которые я ожидаю. Но в моем файле applying.xm я не вижу изменений в нем. Любой, пожалуйста, помогите!

Ответы [ 2 ]

3 голосов
/ 14 апреля 2020

twig_handlers - это IMO, одна из особенностей XML::Twig, которая удивительна, но и излишне запутана.

Я бы предложил , а не , используя его, если только вам не нужно постепенно анализировать или предварительно обрабатывать XML.

Так что я бы решил вашу проблему более похожей this:

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;

my $xml = XML::Twig -> new ->parsefile('applying.xml');


#get_xpath finds all characteristics nodes in the tree, and allows you to 
#iterate. "//" means any depth. 
foreach my $element ( $xml -> get_xpath('//characteristics') ) {
   $element -> insert_new_elt ( 'last_child' => 'supportsMVV') -> set_text('true');
}

$xml -> set_pretty_print('indented'); 
$xml -> print;

Он использует get_xpath для обхода дерева XML и поиска всех узлов characteristics, прежде чем изменять каждый из них. Я чувствую, что это одновременно чище и менее запутанно.

Вы также можете использовать xpath для проверки условий в вашем XML, так как XPath является довольно всеобъемлющим способом интерпретации документа XML. Или просто сделайте это «perlishly» внутри повторяющегося элемента.

В любом случае, причина, по которой вы не видите, что ваша вещь меняется, заключается в том, что вы фактически не записываете изменения - $xml -> print; изменяет файл, только если вы делаете parsefile_inplace.

Но я бы посоветовал вам не делать этого - просто сохраните копию вашего вывода.

Например:

open ( my $output, ">", "applying.new.xml" ) or die $!;
$xml -> print ( $output );
0 голосов
/ 14 апреля 2020

Вы читаете данные из файла, вносите изменения в копию данных в памяти, а затем не записываете измененные данные обратно в исходный файл.

В конце вашего кода, вам нужно добавить что-то вроде:

open my $out_fh, '>', 'new_applying.xml' or die $!;

print $out_fh $twig->print;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...