を試してみXML Simple
ましたが、XML をハッシュに読み込むだけなので、DTD に対して実行すると出力が役に立ちません。難しい方法でそれを学びました。
そこで私は を採用XML::LibXML
しました。おもしろいことに、 で達成するのが最も難しい要件がXML::Simple
最も簡単でした。ただし、 で行うのが簡単なことのいくつかXML::Simple
が不可能であることがわかっています (DOM の理解不足と、 でのいくつかの紛らわしい動作によりXML::LibXML
)。
XML のサンプルを次に示します。
<Metadata>
<ADI Name="movie" />
<App_Data Name="Something I don't care about" value="who cares" />
<App_Data Name="Something I don't care about as well" value="who cares" />
<App_Data Name="ChangeMe" Value="" />
</Metadata>
<Metadata>
<ADI Name="photo" />
<App_Data Name="Something I don't care about" value="who cares" />
<App_Data Name="Something I don't care about as well" value="who cares" />
<App_Data Name="ChangeMe" Value="" />
</Metadata>
<Metadata>
<ADI Name="poster" />
<App_Data Name="Something I don't care about" value="who cares" />
<App_Data Name="Something I don't care about as well" value="who cares" />
<App_Data Name="ChangeMe" Value="" />
</Metadata>
注: この投稿で使用するために、これを単純化しました。
したがって、基本的には、タグのName
フィールドを使用して、DOM の正しい領域にいることを確認し、タグの属性を<ADI>
変更する必要があります。Value
<App_Data>
Name
ChangeMe
これは私が思いついたコードのスニペットです...そして惨めに失敗しました。
#!/usr/bin/perl
use strict;
use XML::LibXML;
my $xml2 = XML::LibXML->new();
my $data = $xml2->parse_file("adi.xml");
my $movie;
my $photo;
my $poster;
foreach my $test ($data->findnodes('//Metadata')) {
if ($test->findvalues('./ADI/@Name[.="movie"]')){
$movie = 1;
undef $photo;
undef $poster;
}
elsif ($test->findvalues('./ADI/@Name[.="photo"]')){
undef $movie;
$photo = 1;
undef $poster;
}
elsif ($test->findvalues('./ADI/@Name[.="poster"]')){
undef $movie;
undef $photo;
$poster = 1;
}
}
うまくいかないので、これ以上のものはありません。次のようなエラーが表示されます
Can't locate object method "findvalues" via package "XML::LibXML::Element"
この質問のボーナスとして、<Metadata>
写真やポスターを含むもの (およびすべての子) を完全に削除したい場合はどうすればよいですか?