1

特定の値を持つ属性を持つ要素を見つけて、ドキュメントから削除しようとしています。

この例では、値が「....\TS\ETestScenario.inc」である「RelativePath」という属性を持つ File 要素を探しています。

</Files>問題:スクリプトを実行した後、最後の要素 -がありません。また、'VisualStudioProject' 終了タグが 2 回出力されます。ここで何をしているのかわかりません。

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)=@_;

    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>
4

1 に答える 1

2

前述のとおり、XML は無効であり、コードはコンパイルされません。

つまり、私が正しく理解していれば、ハンドラーは次のようになるはずです。

sub upd_files_section{
    my ($t, $inputFields)=@_;
    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']});
于 2013-08-01T05:03:47.930 に答える