2013-07-31 2 views
1

Я пытаюсь найти элемент с атрибутом с определенным значением и удалить его из документа.Родительский элемент не закрывается после удаления элемента: XML Twig

В этом примере я ищу элемент File с атрибутом «RelativePath», значение которого «.... \ TS \ ETestScenario.inc».

Проблема: последний элемент - </Files> отсутствует после запуска сценария. Кроме того, закрывающий тег «VisualStudioProject» печатается дважды. Не уверен, что я здесь делаю.

use strict; 
use XML::Twig; 
my $fileName = 'Z:\autotest\test.xml'; 
my $t= new XML::Twig(TwigRoots=> 
      { Files => \&upd_files_section 
      }, 

       twig_print_outside_roots => 1,    # print the rest 
       keep_spaces => 1, 
       keep_atts_order=>1, 
      );    

$t->parsefile("$fileName"); 
#$t->parsefile_inplace ("$fileName"); 


sub upd_files_section{ 
    my ($t, $inputFields)[email protected]_; 

    my $file_to_delete = $inputFields->get_xpath("./File[\@att='..\..\TS\ETestScenario.inc']"); 
    $inputFields->delete($file_to_delete); 
    $t->flush; 
} 

Некорректное XML Выход:

<VisualStudioProject 
    ProjectType="Visual C++" 
    Version="8.00" 
    Name="xxx" 
    ProjectGUID="{}" 
    RootNamespace="xx" 
    SccProjectName="x" 
    SccLocalPath="." 
    SccProvider="x" 
    > 
     <Files> 
       <Filter Name="Source Files" Filter="cpp;bat"> 
         <File RelativePath="..\..\TS\ADK_MacCommon_Test.cpp"> 
         </File> 
         <File RelativePath="..\..\FSO\EADK.cpp"> 
         </File> 
       <Filter Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" Name="Resource Files"> 
       </Filter> 
       <File RelativePath="..\..\TS\ETestScenario.inc"> 
       </File> 
     </VisualStudioProject> 
     <Globals> 
     </Globals> 
</VisualStudioProject> 
+0

Удалите флеш или замените его на «чистку». – choroba

+0

Либо ваш скрипт perl, и ваш xml имеют ошибки. Исправьте их, если вы ждете лучших ответов. – Birei

+0

Я обновил код до его компиляции. XML неверен, что это моя проблема. Решение от mirod ниже работает как charm.THANKS !! но, как только ускользает обратная косая черта, я думал, что мне не придется, поскольку строка находится в одинарных кавычках. – JayT

ответ

2

Как уже упоминалось, XML не является действительным, а код не компилируется.

что сказал, если я правильно понимаю, я думаю, что обработчик должен быть:

sub upd_files_section{ 
    my ($t, $inputFields)[email protected]_; 
    my @files_to_delete = $inputFields->get_xpath("./File[\@RelativePath='..\\..\\TS\\ETestScenario.inc']"); 
    foreach my $file (@files_to_delete) { $file->delete; } 
    $t->flush; 
} 

Несколько замечаний:

  • вам нужно, чтобы избежать обратной косой черты в выражении XPath, или Perl считает, что они чтобы избежать следующего символа; в качестве альтернативы, использовать простые кавычки или q{} вокруг выражения: q{./File[@RelativePath='..\..\TS\ETestScenario.inc']}
  • в выражении XPath, это должно быть @RelativePath, не @att
  • get_xpath возвращает список элементов, которые вы должны удалить
  • удалить вызов элемента delete на нем, нет необходимости проходить через своего родителя, как с DOM
  • вы также можете вырезать всех детей сразу, используя ... cut_children метод: $inputFields->cut_children(q{File[@RelativePath='..\..\TS\ETestScenario.inc']});
Смежные вопросы