【问题标题】:Parsing xml with perl and libXML用 perl 和 libXML 解析 xml
【发布时间】:2014-05-01 04:27:40
【问题描述】:

我有一个 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 

好的,尝试将 ue 缩放到个人资料。不确定如何遍历子节点。试过这个。但它也没有打印正确的值

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";
}

【问题讨论】:

    标签: xml perl parsing ffmpeg libxml2


    【解决方案1】:

    好的,当您到达脚本末尾时,@nodeListXML::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,将结果放入数组中,然后处理数组的第一个元素。

    【讨论】:

    • 你好,艾丹,是的,我编辑了转储文件。在我的帖子中添加了源 XML 文件
    • 不确定如何使用您所说的内容。这里绝对是新手 :-)
    • 感谢艾丹!我快到了。检查我的帖子,我如何将元数据节点中的文件名和配置文件名称添加到输出字符串。
    • 您需要“缩小”并找到然后迭代profiles 而不是enodingParams。然后就差不多了……
    • 缩小是指使用兄弟节点还是父节点
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 2017-10-24
    • 2015-02-04
    相关资源
    最近更新 更多