我有一个XML文件,我想解析并用它来为ffmpeg编码创建一个参数集。
这就是xml的转储:
$VAR1 = {
'profile' => [
{
'enodingParam' => {
'videoFrameRate' => {
'arg' => '-r',
'content' => '25'
},
'audioCodec' => {
'arg' => '-acodec',
'content' => 'libfaac'
},
'videoCodec' => {
'arg' => '-vcodec',
'content' => 'libx264'
},
'videoSize' => {
'arg' => '-s',
'content' => '640x360'
},
'audioBitrate' => {
'arg' => '-ab',
'content' => '96k'
},
'videoGOP' => {
'arg' => '-g',
'content' => '90'
},
'audioRate' => {
'arg' => '-ar',
'content' => '22050'
},
'audioChannels' => {
'arg' => '-ac',
'content' => '2'
},
'videoPreset' => {
'arg' => '-vpre',
'content' => 'slow'
},
'videoBitrate' => {
'arg' => '-b',
'content' => '1200k'
}
},
'metadat' => {
'fileContainer' => '.mp4',
'profileName' => 'testpfrof1'
}
},
{
'enodingParam' => {
'videoFrameRate' => {
'arg' => '-r',
'content' => '25'
},
'audioCodec' => {
'arg' => '-acodec',
'content' => 'libfaac'
},
'videoCodec' => {
'arg' => '-vcodec',
'content' => 'libx264'
},
'videoSize' => {
'arg' => '-s',
'content' => '320x180'
},
'audioBitrate' => {
'arg' => '-ab',
'content' => '96k'
},
},
'videoGOP' => {
'arg' => '-g',
'content' => '90'
},
'audioRate' => {
'arg' => '-ar',
'content' => '22050'
},
'audioChannels' => {
'arg' => '-ac',
'content' => '2'
},
'videoPreset' => {
'arg' => '-vpre',
'content' => 'slow'
},
'videoBitrate' => {
'arg' => '-b',
'content' => '400k'
}
},
'metadat' => {
'fileContainer' => '.mp4',
'profileName' => 'testProfile2'
}
}
]
};
我想为encodingparam节点/标记名使用foreach循环,最后得到一个如下所示的字符串:
-acodec libfaac -vcodec libx264 -s 640x360 -ab 96k
我有点卡住了。这就是我到目前为止所做的:
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
use XML::LibXML;
my $filename = "xml/profile.xml";
my $parser = XML::LibXML->new;
my $doc = $parser->parse_file($filename)
or die "can't parse profile file: $@";
my $root = $doc->documentElement();
my @nodeList = $doc->getElementsByTagName('enodingParam');
这是xml文件
<?xml version="1.0"?>
<profiles>
<profile>
<metadt>
<profileName>testp1</profileName>
<fileContainer>.mp4</fileContainer>
</metadt>
<enodingParam>
<videoCodec arg="-vcodec">libx264</videoCodec>
<videoPreset arg="-vpre">slow</videoPreset>
<videoBitrate arg="-b">1200k</videoBitrate>
<videoWidth arg="-w">640</videoWidth>
<videoHeight arg="-h">360</videoHeight>
<videoSize arg="-s">640x360</videoSize>
<videoFrameRate arg="-r">25</videoFrameRate>
<videoGOP arg ="-g">90</videoGOP>
<audioBitrate arg="-ab">ab 96k</audioBitrate>
<audioCodec arg="-acodec">-acodec libfaac</audioCodec>
<audioChannels arg="-ac">2</audioChannels>
<audioRate arg="-ar">"22050"</audioRate>
</enodingParam>
</profile>
<profile>
<metadt>
<profileName>testProfile22</profileName>
<fileContainer>.mp4</fileContainer>
</metadt>
<enodingParam>
<videoCodec arg="-vcodec">libx264</videoCodec>
<videoPreset arg="-vpre">slow</videoPreset>
<videoBitrate arg="-b">1200k</videoBitrate>
<videoWidth arg="-w">640</videoWidth>
<videoHeight arg="-h">360</videoHeight>
<videoSize arg="-s">640x360</videoSize>
<videoFrameRate arg="-r">25</videoFrameRate>
<videoGOP arg ="-g">90</videoGOP>
<audioBitrate arg="-ab">96k</audioBitrate>
<audioCodec arg="-acodec">libfaac</audioCodec>
<audioChannels arg="-ac">2</audioChannels>
<audioRate arg="-ar">22050</audioRate>
</enodingParam>
</profile>
</profiles>
将pl脚本修改为
use warnings;
use strict;
use Data::Dumper;
use XML::LibXML;
my $filename = "xml/book.xml";
my $parser = XML::LibXML->new;
my @ffmpegargs;
my $fileName="filename";
my $doc = $parser->parse_file($filename)
or die "can't parse profile file: $@";
my $root = $doc->documentElement();
my @paramList = $doc->getElementsByTagName('enodingParam');
for my $ele (@paramList)
{
# You then need to iterate over all the children of that node...
for my $param ($ele->nonBlankChildNodes())
{
my $inparams = " " . $param->getAttribute('arg') . " " . $param->textContent ;
push ( @ffmpegargs, $inparams);
}
my $ffmpeg = join(" ", @ffmpegargs);
print "ffmpeg" . $ffmpeg, "\n";
}
正确打印出来。现在我如何将以下内容添加到字符串中 $ filename,profileName,containerName(来自metadat节点)到相同的字符串,以便我的最终输出如下所示:
ffmpeg -vcodec libx264 -vpre slow -b 1200k -w 640 -h 360 -s 640x360 filename_profileName_containerName
确定尝试缩放你的个人资料。不确定如何遍历子节点。试过这个。但它也不打印正确的值
use warnings;
use strict;
use Data::Dumper;
use XML::LibXML;
my $filename = "xml/book.xml";
my $parser = XML::LibXML->new;
my @ffmpegargs;
my $fileName="filename";
my $doc = $parser->parse_file($filename)
or die "can't parse profile file: $@";
my $root = $doc->documentElement();
my @paramList = $doc->getElementsByTagName('profile');
for my $ele (@paramList)
{
# You then need to iterate over all the children of that node...
for my $param ($ele->findnodes('/encodingParam/*'))
{
my $inparams = " " . $param->getAttribute('arg') . " " . $param->textContent ;
push ( @ffmpegargs, $inparams);
}
my $ffmpeg = join(" ", @ffmpegargs);
print "ffmpeg" . $ffmpeg, "\n";
}
答案 0 :(得分:1)
好的,当你到达脚本结束时,@nodeList
是XML::LibXML::Element
个对象的列表。
因此,您首先遍历该列表的每个元素:
my @profiles = $doc->getElementsByTagName('profile');
for my $profile (@profiles)
{
print $profile->getElementsByTagName('profileName')->get_node(1)->textContent;
print $profile->getElementsByTagName('fileContainer')->get_node(1)->textContent;
for my $param ($profile->getElementsByTagName('enodingParam')->get_node(1)->nonBlankChildNodes())
{
print " ";
print $param->getAttribute('arg');
print " ";
print $param->textContent;
}
print "\n";
}
我使用get_node(1)
作为快捷方式,而不是调用getElementsByTagName
,将结果放入数组中,然后处理数组的第一个元素。