私は、次のようないくつかのXMLファイルを持っている:PerlのXML :: Twigを使って要素を削除する方法はありますか?
<machines>
<server>
127.0.0.1
</server>
<proxy>
<ip>127.0.0.2</ip>
<etc>abc</etc>
</proxy>
</machines>
と私は、サーバーを維持し、他の人を削除すると、出力は次のようになります。次のように
<machines>
<server>
127.0.0.1
</server>
</machines>
私は、スクリプトを書いた:
use warnings;
use strict;
use feature ':5.10';
use XML::Twig;
my $path='C:\strawberry\perl\site\lib\file.xml';
my $filehandle;
my $tweak_server =sub{
my ($twig, $root) [email protected]_;
my $elt=$root;
while($elt=$elt->next_elt($root)){
my $tag=$elt->tag;
say $tag;
if ($tag!~/server/){
$elt->delete($tag);
}
}
$twig->flush;
};
open($filehandle, "+<$path") or die "cannot open out file out_file:$!";
my $roots = { machines => 1 };
my $handlers = { 'machines' => $tweak_server,
};
my $twig = new XML::Twig(TwigRoots => $roots,
TwigHandlers => $handlers,
pretty_print => 'indented'#,
# twig_print_outside_roots => \*$filehandle
);
$twig->parsefile($path);
close $filehandle;
出力を得ました。
server
#PCDATA
<machines>
<server></server>
<proxy>
<ip>127.0.0.2</ip>
<etc>abc</etc>
</proxy>
</machines>
「#PCDATA」がなぜ存在するのか、なぜ期待していないのはなぜうまくいかないのか分かりません。
use warnings;
use strict;
use feature ':5.10';
use XML::Twig;
my $tweak_server =sub{
my ($twig, $root) [email protected]_;
my $elt=$root;
my $text=$elt->first_child_text('id');
if ($text=~m/12/){
while($elt=$elt->next_elt('#ELT')){
my $tag=$elt->tag;
say $tag;
if ($tag!~/id/){
$elt->delete;
}
}
}
};
my $roots = { machines => 1 };
my $handlers = { 'machines/aaa' => $tweak_server,
};
my $twig =XML::Twig->new(TwigRoots => $roots,
TwigHandlers => $handlers,
pretty_print => 'indented'#,
# twig_print_outside_roots => \*$filehandle
)
->parse(\*DATA)
->print;
__DATA__
<machines>
<server> 127.0.0.1 </server>
<aaa>
<id>12</id>
<ip>127.0.0.2</ip>
<option>127.0.0.6</option>
<etc>abc</etc>
</aaa>
<aaa>
<id>14</id>
<ip>127.0.0.2</ip>
<etc>abc</etc>
</aaa>
<aaa>
<id>15</id>
<ip>127.0.0.2</ip>
<etc>abc</etc>
</aaa>
</machines>
、出力は次のとおりです:次のように私が試した
@mirod
<machines>
<server> 127.0.0.1 </server>
<aaa>
<id>12</id>
<option>127.0.0.6</option>
<etc>abc</etc>
</aaa>
<aaa>
<id>14</id>
<ip>127.0.0.2</ip>
<etc>abc</etc>
</aaa>
<aaa>
<id>15</id>
<ip>127.0.0.2</ip>
<etc>abc</etc>
</aaa>
</machines>
と私がしたいだけではなく1、三つの要素を削除するには、次のとおりです。
<ip>127.0.0.2</ip>
<option>127.0.0.6</option>
<etc>abc</etc>
要素下
<id>12</id>
ご意見はありますか?
あなたが '#のPCDATA'を取得:すべての残りの部分を破棄しながら、これは、XMLおよびサーバー要素(とその内容)のルートを維持する効果があります。実際の要素をループしたい場合は、 '$ elt-> next_elt( '#ELT')'を使います。 – mirod
twig.pmにありがとう、私はちょうどitem = next_elt($ optional_elt、$ optional_condition)を見つけたので、 '#ELT'は最初の引数にすることができますか? – trivial
いいえ、両方の引数はオプションで、その型が異なるため(スカラー対XML :: Twig :: Elt)、メソッドはどちらが使用されているか把握することができます。それを試してみてください! – mirod