Как вернуть отдельные результаты, используя XML::LibXML
В настоящее время я пытаюсь использовать следующий код Perl для фильтрации XML-документа по конкретным значениям.
use 5.010;
use strict;
use warnings;
use XML::LibXML;
my $filename = 'FF_BLADEII###_UNCP_12_Clips.xml';
my $dom = XML::LibXML->load_xml(location => $filename);
my $count = 1 ;
foreach my $node($dom->findnodes('//xmeml/sequence/media/video/track')) {
say 'Track Name:', $node->findvalue('./@MZ.TrackName');
say 'Clip item', $count++ ;
say 'Frame Rate:', $node->findvalue('./clipitem/rate/timebase'),;
say 'Timecode In:', $node->findvalue('./clipitem/start');
say 'Timecode Out:', $node->findvalue('./clipitem/end');
}
В настоящее время я получаю вывод
Track Name:FF_BLADEII###_UNCP
Clip item1
Frame Rate:252525252525
Timecode In:01125120004800093000138004
Timecode Out:1125120004800093000138004179424
Track Name:CE_FF_BLADEII###_01_FUSED
Clip item2
Frame Rate:252525252525
Timecode In:01125120004800093000138004
Timecode Out:1125120004800093000138004167125
Где, например, каждый результат для Frame Rate
отображается в одной строке. Я знаю, что это происходит, потому что есть шесть timebase
элементы в каждом track
, но мой желаемый результат будет в списке Track Name
атрибут, а затем значения от каждого clipitem
Элемент внутри него отдельно. Например
Track Name:FF_BLADEII###_UNCP
Clip item1
Frame Rate:25
Timecode In:0
Timecode Out:1125
Clip item2
Frame Rate:25
Timecode In:1125
Timecode Out:12000
Clip item3
Frame Rate:25
Timecode In:12000
Timecode Out:48000
Clip item4
Frame Rate:25
Timecode In:48000
Timecode Out:93000
Clip item5
Frame Rate:25
Timecode In:93000
Timecode Out:138004
Clip item6
Frame Rate:25
Timecode In:138004
Timecode Out:179424
Track Name:CE_FF_BLADEII###_01_FUSED
Clip item1
Frame Rate:25
Timecode In:0
Timecode Out:1125
Clip item2
Frame Rate:25
Timecode In:1125
Timecode Out:12000
Clip item3
Frame Rate:25
Timecode In:12000
Timecode Out:48000
Clip item4
Frame Rate:25
Timecode In:48000
Timecode Out:93000
Clip item5
Frame Rate:25
Timecode In:93000
Timecode Out:138004
Clip item6
Frame Rate:25
Timecode In:138004
Timecode Out:167125
Вот исходный XML, который я использую
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xmeml>
<xmeml version="4">
<sequence id="sequence-2" TL.SQAudioVisibleBase="9" TL.SQVideoVisibleBase="0" TL.SQVisibleBaseTime="0" TL.SQAVDividerPosition="0.5" TL.SQHideShyTracks="0" TL.SQHeaderWidth="184" Monitor.ProgramZoomOut="499578347520000" Monitor.ProgramZoomIn="474176747520000" TL.SQTimePerPixel="11.015524079320114" MZ.EditLine="487629434880000" MZ.Sequence.PreviewFrameSizeHeight="1080" MZ.Sequence.PreviewFrameSizeWidth="1920" MZ.Sequence.PreviewRenderingClassID="1480868673" MZ.Sequence.PreviewRenderingPresetCodec="107" MZ.Sequence.EditingModeGUID="44cf6a27-e791-427a-a544-97439b366abf" MZ.Sequence.VideoTimeDisplayFormat="109" MZ.WorkOutPoint="1823062671360000" MZ.WorkInPoint="0" MZ.ZeroPoint="883975680000000" explodedTracks="true">
<rate>
<timebase>25</timebase>
<ntsc>FALSE</ntsc>
</rate>
<name>FF_BLADEII###_UNCP</name>
<media>
<video>
<track TL.SQTrackShy="0" TL.SQTrackExpandedHeight="50" TL.SQTrackExpanded="1" MZ.TrackTargeted="1" MZ.TrackName="FF_BLADEII###_UNCP">
<clipitem id="clipitem-73" frameBlend="FALSE">
<masterclipid>masterclip-3</masterclipid>
<name>FF_BLADEII###_UNCP</name>
<enabled>TRUE</enabled>
<duration>181474</duration>
<rate>
<timebase>25</timebase>
<ntsc>FALSE</ntsc>
</rate>
<start>0</start>
<end>1125</end>
<in>0</in>
<out>1125</out>
</clipitem>
<clipitem id="clipitem-74" frameBlend="FALSE">
<masterclipid>masterclip-3</masterclipid>
<name>FF_BLADEII###_UNCP</name>
<enabled>TRUE</enabled>
<duration>181474</duration>
<rate>
<timebase>25</timebase>
<ntsc>FALSE</ntsc>
</rate>
<start>1125</start>
<end>12000</end>
<in>1175</in>
<out>12050</out>
</clipitem>
<clipitem id="clipitem-75" frameBlend="FALSE">
<masterclipid>masterclip-3</masterclipid>
<name>FF_BLADEII###_UNCP</name>
<enabled>TRUE</enabled>
<duration>181474</duration>
<rate>
<timebase>25</timebase>
<ntsc>FALSE</ntsc>
</rate>
<start>12000</start>
<end>48000</end>
<in>12550</in>
<out>48550</out>
</clipitem>
<clipitem id="clipitem-76" frameBlend="FALSE">
<masterclipid>masterclip-3</masterclipid>
<name>FF_BLADEII###_UNCP</name>
<enabled>TRUE</enabled>
<duration>181474</duration>
<rate>
<timebase>25</timebase>
<ntsc>FALSE</ntsc>
</rate>
<start>48000</start>
<end>93000</end>
<in>48550</in>
<out>93550</out>
</clipitem>
<clipitem id="clipitem-77" frameBlend="FALSE">
<masterclipid>masterclip-3</masterclipid>
<name>FF_BLADEII###_UNCP</name>
<enabled>TRUE</enabled>
<duration>181474</duration>
<rate>
<timebase>25</timebase>
<ntsc>FALSE</ntsc>
</rate>
<start>93000</start>
<end>138004</end>
<in>95050</in>
<out>140054</out>
</clipitem>
<clipitem id="clipitem-78" frameBlend="FALSE">
<masterclipid>masterclip-3</masterclipid>
<name>FF_BLADEII###_UNCP</name>
<enabled>TRUE</enabled>
<duration>181474</duration>
<rate>
<timebase>25</timebase>
<ntsc>FALSE</ntsc>
</rate>
<start>138004</start>
<end>179424</end>
<in>140054</in>
<out>181474</out>
</clipitem>
</track>
<track TL.SQTrackShy="0" TL.SQTrackExpandedHeight="25" TL.SQTrackExpanded="0" MZ.TrackTargeted="0" MZ.TrackName="CE_FF_BLADEII###_01_FUSED">
<clipitem id="clipitem-79" frameBlend="FALSE">
<masterclipid>masterclip-4</masterclipid>
<name>CE_FF_BLADEII###_01</name>
<enabled>TRUE</enabled>
<duration>169175</duration>
<rate>
<timebase>25</timebase>
<ntsc>FALSE</ntsc>
</rate>
<start>0</start>
<end>1125</end>
<in>0</in>
<out>1125</out>
</clipitem>
<clipitem id="clipitem-80" frameBlend="FALSE">
<masterclipid>masterclip-4</masterclipid>
<name>CE_FF_BLADEII###_01</name>
<enabled>TRUE</enabled>
<duration>169175</duration>
<rate>
<timebase>25</timebase>
<ntsc>FALSE</ntsc>
</rate>
<start>1125</start>
<end>12000</end>
<in>1175</in>
<out>12050</out>
</clipitem>
<clipitem id="clipitem-81" frameBlend="FALSE">
<masterclipid>masterclip-4</masterclipid>
<name>CE_FF_BLADEII###_01</name>
<enabled>TRUE</enabled>
<duration>169175</duration>
<rate>
<timebase>25</timebase>
<ntsc>FALSE</ntsc>
</rate>
<start>12000</start>
<end>48000</end>
<in>12550</in>
<out>48550</out>
</clipitem>
<clipitem id="clipitem-82" frameBlend="FALSE">
<masterclipid>masterclip-4</masterclipid>
<name>CE_FF_BLADEII###_01</name>
<enabled>TRUE</enabled>
<duration>169175</duration>
<rate>
<timebase>25</timebase>
<ntsc>FALSE</ntsc>
</rate>
<start>48000</start>
<end>93000</end>
<in>48550</in>
<out>93550</out>
</clipitem>
<clipitem id="clipitem-83" frameBlend="FALSE">
<masterclipid>masterclip-4</masterclipid>
<name>CE_FF_BLADEII###_01</name>
<enabled>TRUE</enabled>
<duration>169175</duration>
<rate>
<timebase>25</timebase>
<ntsc>FALSE</ntsc>
</rate>
<start>93000</start>
<end>138004</end>
<in>95050</in>
<out>140054</out>
</clipitem>
<clipitem id="clipitem-84" frameBlend="FALSE">
<masterclipid>masterclip-4</masterclipid>
<name>CE_FF_BLADEII###_01</name>
<enabled>TRUE</enabled>
<duration>169175</duration>
<rate>
<timebase>25</timebase>
<ntsc>FALSE</ntsc>
</rate>
<start>138004</start>
<end>167125</end>
<in>140054</in>
<out>169175</out>
</clipitem>
</track>
</video>
</media>
</sequence>
</xmeml>
1 ответ
Вы уже сделали правильную вещь, используя $node
для треков (хотя $track
было бы лучшим именем) и нет необходимости в ./
в начале выражений XPath. Просто откройте еще одну петлю для clipitem
элементы, как это
for my $track ( $dom->findnodes('//xmeml/sequence/media/video/track') ) {
say 'Track Name: ', $track->findvalue('@MZ.TrackName');
my $count;
for my $clip ( $track->findnodes('clipitem') ) {
say 'Clip item', ++$count;
say 'Frame Rate: ', $clip->findvalue('rate/timebase');
say 'Timecode In: ', $clip->findvalue('start');
say 'Timecode Out: ', $clip->findvalue('end');
}
say "";
}
Я также подозреваю, что двойная косая черта не нужна //
в начале XPath для track
, Это просто делает LibXML поиск по всем данным вместо проверки в корневом элементе, и если xmeml
является корневым элементом, тогда нет необходимости: только одна косая черта является правильной.