如何使用Perl编辑XML文件?
我有一个电影收藏目录,带有文件夹和文件的本地链接,便于访问。最近,我重新整理了我的整个硬盘空间,我需要更新链接,我正试图用Perl自动完成这项工作 我可以将数据导出到XML文件中,然后再次导入。我可以使用提取新的文件路径,但我遇到了两个问题。我不知道如何将新文件路径中的如何使用Perl编辑XML文件?,xml,perl,Xml,Perl,我有一个电影收藏目录,带有文件夹和文件的本地链接,便于访问。最近,我重新整理了我的整个硬盘空间,我需要更新链接,我正试图用Perl自动完成这项工作 我可以将数据导出到XML文件中,然后再次导入。我可以使用提取新的文件路径,但我遇到了两个问题。我不知道如何将新文件路径中的$title与XML文件中相应的$title连接起来。我第一次处理这样的文件,我不知道如何进行替换过程。这就是我到现在为止所做的 use strict; use warnings; use File::Basename; us
$title
与XML文件中相应的$title
连接起来。我第一次处理这样的文件,我不知道如何进行替换过程。这就是我到现在为止所做的
use strict;
use warnings;
use File::Basename;
use File::Find;
use File::Spec;
use XML::Simple;
use Data::Dumper;
my $dir_target = 'D:/Movies/';
my %titles_locations = ();
find(\&file_handler, $dir_target);
sub file_handler {
/\.iso$/ or return;
my $fn = $File::Find::name;
$fn =~ s/\//\\/g;
$fn =~ /(.*\\)(.*)/;
my $path = $1;
my $filename = $2;
my $title = (File::Spec->splitdir($fn))[2];
$title =~ s/(.*?)\s\(\d+\)$/$1/;
$title =~ s/~/:/;
$title =~ s/`/?/;
my $link_local = '<link><description>Folder</description><url>'.$path.'</url><urltype>Movie</urltype></link><link><description>'.$filename.'</description><url>'.$fn.'</url><urltype>Movie</urltype></link>' unless $title eq '';
$titles_locations{$title} = {'filename'=>$filename, 'path'=>$path };
}
my $xml_in = XMLin('somepath/test.xml', ForceArray => 1, KeepRoot => 1);
my $title = {'key1' => 'title', 'key2' => 'links'};
foreach my $link (keys %$title) {
}
print Data::Dumper->Dump([$title]);
my $xml_out = XMLout($xml_in, OutputFile => 'somepath/test_out.xml', KeepRoot=>1);
使用严格;
使用警告;
使用File::Basename;
使用File::Find;
使用File::Spec;
使用XML::Simple;
使用数据::转储程序;
我的$dir_目标='D:/Movies/';
我的%titles_位置=();
查找(\&file\u处理程序,$dir\u目标);
子文件处理程序{
/\.iso$/或退货;
我的$fn=$File::Find::name;
$fn=~s/\/\\\/g;
$fn=~/(.\\)(.*)/;
我的$path=$1;
我的$filename=$2;
我的$title=(File::Spec->splitdir($fn))[2];
$title=~s/(.*)\s\(\d+\)$/$1/;
$title=~s/~/:/;
$title=~s/`/;
my$link_local='Folder'.$path.'Movie'.$filename'.$fn.'Movie'除非$title eq'';
$titles\u位置{$title}={'filename'=>$filename,'path'=>$path};
}
my$xml_in=XMLin('somepath/test.xml',ForceArray=>1,KeepRoot=>1);
我的$title={'key1'=>'title','key2'=>'links'};
foreach my$链接(键%$标题){
}
打印数据::转储程序->转储([$title]);
我的$xml\u out=XMLout($xml\u-in,OutputFile=>somepath/test\u-out.xml',KeepRoot=>1);
这是我需要编辑的数据片段。
如果发现imdb和DVD链接-请勿触摸。
如果找到本地链接,请替换,否则请插入。
我愿意自己完成代码,但需要一些指导如何进一步进行。
谢谢
$title
.......
IMDB
http://www.imdb.com/title/VARIABLE
统一资源定位地址
DVD帝国
http://www.dvdempire.com/VARIABLE
统一资源定位地址
文件夹
老路
电影
旧文件名
旧文件名路径
电影
我将提供一个合理的方法-如果您希望它更加充实,请发表评论
my%titles_locations=()代码>在开头
sub a
(请称之为可读的,比如sub file\u handler
:)
文件处理程序应该做的是:
- 像现在一样构建
和$title
$link\u local
- 将它们存储在
散列中,其中%titles\u位置
是键,hashref包含的值为$title
{'filename'=>$filename',path'=>$path}
find()
之后,您将调用XMLin$xml_in
应成为一个hashref数组(或将“root”键映射到一个hashref数组的hashref)。数组中的每个hashref将代表一个标题$title
)将是一个具有两个键的hashref,“title”
和“links”
从“title”
键的值中,从%titles\u位置
哈希中查找新路径和文件名
“links”
键的值将是一个hashref映射“link”到一个hashref数组。我不想在这里详细说明数据结构,但通过打印data::Dumper->Dump([$title]);
然后,您将在这些链接hashref上循环。对于每个链接(称为$link
):
- 如果
ne“Movie”,请不要管它($link->{urltype}
)next;
- 如果
eq“文件夹”,则将$link->{description}
值替换为从$link->{url}
哈希中找到的新路径%titles\u位置
- 否则,它是一个文件,用从
散列中找到的新文件路径替换%titles\u locations
值$link->{url}
$title
不在%titles\u位置
哈希中,可能会添加一些错误处理$xml\u放入
(现在包含更新的信息)并传递到XMLout()
%new\u paths
:
#!perl
use File::Basename qw(basename);
use XML::Twig;
my %new_paths = (
# filename => new_path
...
);
my $twig = XML::Twig->new(
twig_handlers =>
{
link => \&rewrite_link,
},
pretty_print => 'indented',
);
$twig->parse( *DATA );
$twig->flush;
sub rewrite_link
{
my( $link ) = $_;
return unless $link->field( 'urltype' ) eq 'Movie';
# this is from the old file
my $basename = basename( $link->field( 'url' ) );
unless( exists $new_paths{ $basename } )
{
warn "Didn't find a new location for $basename!\n";
return;
}
$link->first_child( 'url' )->set_text( $new_paths{ $basename } );
}
__END__
<titles>
<entry>
<title>$title</title>
<links>
<link>
<description>IMDB</description>
<url>http://www.imdb.com/title/VARIABLE</url>
<urltype>URL</urltype>
</link>
<link>
<description>DVD Empire</description>
<url>http://www.dvdempire.com/VARIABLE</url>
<urltype>URL</urltype>
</link>
<link>
<description>Folder</description>
<url>OLD_FOLDERPATH</url>
<urltype>Movie</urltype>
</link>
<link>
<description>OLD_FILENAME</description>
<url>OLD_FILENAMEPATH</url>
<urltype>Movie</urltype>
</link>
</links>
</entry>
</titles>
#!perl
使用文件::Basename qw(Basename);
使用XML::Twig;
我的%new_路径=(
#filename=>新路径
...
);
my$twig=XML::twig->new(
细枝处理程序=>
{
link=>\&重写链接,
},
漂亮的打印=>“缩进”,
);
$twig->parse(*数据);
$twig->flush;
子重写链接
{
我的($link)=$\;
返回,除非$link->field('urltype')eq'Movie';
#这是旧档案中的
我的$basename=basename($link->field('url'));
除非(存在$new_路径{$basename})
{
警告“未找到$basename的新位置!\n”;
返回;
}
$link->first_child('url')->set_text($new_path{$basename});
}
__结束__
$title
IMDB
http://www.imdb.com/title/VARIABLE
统一资源定位地址
DVD帝国
http://www.dvdempire.com/VARIABLE
统一资源定位地址
文件夹
老路
电影
#!perl
use File::Basename qw(basename);
use XML::Twig;
my %new_paths = (
# filename => new_path
...
);
my $twig = XML::Twig->new(
twig_handlers =>
{
link => \&rewrite_link,
},
pretty_print => 'indented',
);
$twig->parse( *DATA );
$twig->flush;
sub rewrite_link
{
my( $link ) = $_;
return unless $link->field( 'urltype' ) eq 'Movie';
# this is from the old file
my $basename = basename( $link->field( 'url' ) );
unless( exists $new_paths{ $basename } )
{
warn "Didn't find a new location for $basename!\n";
return;
}
$link->first_child( 'url' )->set_text( $new_paths{ $basename } );
}
__END__
<titles>
<entry>
<title>$title</title>
<links>
<link>
<description>IMDB</description>
<url>http://www.imdb.com/title/VARIABLE</url>
<urltype>URL</urltype>
</link>
<link>
<description>DVD Empire</description>
<url>http://www.dvdempire.com/VARIABLE</url>
<urltype>URL</urltype>
</link>
<link>
<description>Folder</description>
<url>OLD_FOLDERPATH</url>
<urltype>Movie</urltype>
</link>
<link>
<description>OLD_FILENAME</description>
<url>OLD_FILENAMEPATH</url>
<urltype>Movie</urltype>
</link>
</links>
</entry>
</titles>