Вычислить продолжительность анимации SVG в Delphi
Есть анимации в формате SVG. Задача состоит в том, чтобы высчитать её продолжительность. Поскольку анимация может быть бесконечной, мне необходимо высчитать время одного цикла воспроизведения анимации. По своей структуре файл анимации SVG имеет структуру XML. Проверял несколько выборочно на XML-валидаторах, структура правильная. Мне нужно распарсить файл анимации таким образом чтобы получить в итоге наибольшее значение времени. Задача не совсем простая. В файле анимации есть два тэга, которые отвечают за время, это: begin - начало и dur - длительность. Суть в том, что первого тэга может не быть, и по умолчанию его значение нужно будет ставить равным 0. Также он может он присутствовать, и иметь любое значение.
Вот что должно в итоге получиться, мне нужно получить в итоге одну наибольшую цифру, которая получится в результате, она и будет являться длительностью одного цикла анимации.
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="450px" height="279px" viewBox="0 0 450 279" enable-background="new 0 0 450 279" xml:space="preserve">
<g id="Layer_1">
<line fill="none" stroke="#6C54C9" stroke-width="6" stroke-miterlimit="10" x1="9" y1="217" x2="81" y2="172" opacity=".65">
<animate attributeName="y1" from="217" to="217" begin="0s" dur="4s" values="217;244;244;208;208;217;217" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
<animate attributeName="y2" from="172" to="172" begin="0s" dur="4s" values="172;235;235;217;217;172;172" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</line>
<line fill="none" stroke="#6C54C9" stroke-width="6" stroke-miterlimit="10" x1="81" y1="172" x2="153" y2="181" opacity=".65">
<animate attributeName="y1" from="172" to="172" begin="0s" dur="4s" values="172;235;235;217;217;172;172" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
<animate attributeName="y2" from="153" to="153" begin="0s" dur="4s" values="153;99;99;144;144;153;153" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</line>
<line fill="none" stroke="#6C54C9" stroke-width="6" stroke-miterlimit="10" x1="153" y1="181" x2="225" y2="145" opacity=".65">
<animate attributeName="y1" from="153" to="153" begin="0s" dur="4s" values="153;99;99;144;144;153;153" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
<animate attributeName="y2" from="145" to="145" begin="0s" dur="4s" values="145;63;63;108;108;145;145" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</line>
<line fill="none" stroke="#6C54C9" stroke-width="6" stroke-miterlimit="10" x1="225" y1="145" x2="297" y2="55" opacity=".65">
<animate attributeName="y1" from="145" to="145" begin="0s" dur="4s" values="145;63;63;108;108;145;145" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
<animate attributeName="y2" from="55" to="55" begin="0s" dur="4s" values="55;45;45;63;63;55;55" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</line>
<line fill="none" stroke="#6C54C9" stroke-width="6" stroke-miterlimit="10" x1="297" y1="55" x2="369" y2="72" opacity=".65">
<animate attributeName="y1" from="55" to="55" begin="0s" dur="4s" values="55;45;45;63;63;55;55" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
<animate attributeName="y2" from="72" to="72" begin="0s" dur="4s" values="72;63;63;99;99;72;72" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</line>
<line fill="none" stroke="#6C54C9" stroke-width="6" stroke-miterlimit="10" x1="369" y1="72" x2="441" y2="45" opacity=".65">
<animate attributeName="y1" from="72" to="72" begin="0s" dur="4s" values="72;63;63;99;99;72;72" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
<animate attributeName="y2" from="45" to="45" begin="0s" dur="4s" values="45;36;36;54;54;45;45" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</line>
<circle fill="#FFFFFF" stroke="#6C54C9" stroke-width="6" stroke-miterlimit="10" cx="9" cy="217" r="6">
<animate attributeName="cy" from="217" to="217" begin="0s" dur="4s" values="217;244;244;208;208;217;217" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
<circle fill="#FFFFFF" stroke="#6C54C9" stroke-width="6" stroke-miterlimit="10" cx="81" cy="172" r="6">
<animate attributeName="cy" from="172" to="172" begin="0s" dur="4s" values="172;235;235;217;217;172;172" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
<circle fill="#FFFFFF" stroke="#6C54C9" stroke-width="6" stroke-miterlimit="10" cx="153" cy="181" r="6">
<animate attributeName="cy" from="153" to="153" begin="0s" dur="4s" values="153;99;99;144;144;153;153" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
<circle fill="#FFFFFF" stroke="#6C54C9" stroke-width="6" stroke-miterlimit="10" cx="225" cy="145" r="6">
<animate attributeName="cy" from="145" to="145" begin="0s" dur="4s" values="145;63;63;108;108;145;145" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
<circle fill="#FFFFFF" stroke="#6C54C9" stroke-width="6" stroke-miterlimit="10" cx="297" cy="55" r="6">
<animate attributeName="cy" from="55" to="55" begin="0s" dur="4s" values="55;45;45;63;63;55;55" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
<circle fill="#FFFFFF" stroke="#6C54C9" stroke-width="6" stroke-miterlimit="10" cx="369" cy="72" r="6">
<animate attributeName="cy" from="72" to="72" begin="0s" dur="4s" values="72;63;63;99;99;72;72" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
<circle fill="#FFFFFF" stroke="#6C54C9" stroke-width="6" stroke-miterlimit="10" cx="441" cy="45" r="6">
<animate attributeName="cy" from="45" to="45" begin="0s" dur="4s" values="45;36;36;54;54;45;45" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
</g>
<g id="Layer_2">
<line fill="none" stroke="#B450FF" stroke-width="6" stroke-miterlimit="10" x1="9" y1="181" x2="81" y2="208" opacity=".65">
<animate attributeName="y1" from="181" to="181" begin="0s" dur="4s" values="181;171;171;190;190;181;181" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
<animate attributeName="y2" from="208" to="208" begin="0s" dur="4s" values="208;162;162;190;190;208;208" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</line>
<line fill="none" stroke="#B450FF" stroke-width="6" stroke-miterlimit="10" x1="81" y1="208" x2="153" y2="127" opacity=".65">
<animate attributeName="y1" from="208" to="208" begin="0s" dur="4s" values="208;162;162;190;190;208;208" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
<animate attributeName="y2" from="127" to="127" begin="0s" dur="4s" values="127;117;117;90;90;127;127" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</line>
<line fill="none" stroke="#B450FF" stroke-width="6" stroke-miterlimit="10" x1="153" y1="127" x2="225" y2="82" opacity=".65">
<animate attributeName="y1" from="127" to="127" begin="0s" dur="4s" values="127;117;117;90;90;127;127" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
<animate attributeName="y2" from="82" to="82" begin="0s" dur="4s" values="82;127;127;145;145;82;82" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</line>
<line fill="none" stroke="#B450FF" stroke-width="6" stroke-miterlimit="10" x1="225" y1="82" x2="297" y2="118" opacity=".65">
<animate attributeName="y1" from="82" to="82" begin="0s" dur="4s" values="82;127;127;145;145;82;82" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
<animate attributeName="y2" from="118" to="118" begin="0s" dur="4s" values="118;108;108;127;127;118;118" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</line>
<line fill="none" stroke="#B450FF" stroke-width="6" stroke-miterlimit="10" x1="297" y1="118" x2="369" y2="45" opacity=".65">
<animate attributeName="y1" from="118" to="118" begin="0s" dur="4s" values="118;108;108;127;127;118;118" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
<animate attributeName="y2" from="45" to="45" begin="0s" dur="4s" values="45;27;27;36;36;45;45" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</line>
<line fill="none" stroke="#B450FF" stroke-width="6" stroke-miterlimit="10" x1="369" y1="45" x2="441" y2="36" opacity=".65">
<animate attributeName="y1" from="45" to="45" begin="0s" dur="4s" values="45;27;27;36;36;45;45" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
<animate attributeName="y2" from="36" to="36" begin="0s" dur="4s" values="36;12;12;18;18;36;36" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</line>
<circle fill="#FFFFFF" stroke="#B450FF" stroke-width="6" stroke-miterlimit="10" cx="9" cy="181" r="6">
<animate attributeName="cy" from="181" to="181" begin="0s" dur="4s" values="181;171;171;190;190;181;181" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
<circle fill="#FFFFFF" stroke="#B450FF" stroke-width="6" stroke-miterlimit="10" cx="81" cy="208" r="6">
<animate attributeName="cy" from="208" to="208" begin="0s" dur="4s" values="208;162;162;190;190;208;208" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
<circle fill="#FFFFFF" stroke="#B450FF" stroke-width="6" stroke-miterlimit="10" cx="153" cy="127" r="6">
<animate attributeName="cy" from="127" to="127" begin="0s" dur="4s" values="127;117;117;90;90;127;127" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
<circle fill="#FFFFFF" stroke="#B450FF" stroke-width="6" stroke-miterlimit="10" cx="225" cy="82" r="6">
<animate attributeName="cy" from="82" to="82" begin="0s" dur="4s" values="82;127;127;145;145;82;82" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
<circle fill="#FFFFFF" stroke="#B450FF" stroke-width="6" stroke-miterlimit="10" cx="297" cy="118" r="6">
<animate attributeName="cy" from="118" to="118" begin="0s" dur="4s" values="118;108;108;127;127;118;118" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
<circle fill="#FFFFFF" stroke="#B450FF" stroke-width="6" stroke-miterlimit="10" cx="369" cy="45" r="6">
<animate attributeName="cy" from="45" to="45" begin="0s" dur="4s" values="45;27;27;36;36;45;45" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
<circle fill="#FFFFFF" stroke="#B450FF" stroke-width="6" stroke-miterlimit="10" cx="441" cy="36" r="6">
<animate attributeName="cy" from="36" to="36" begin="0s" dur="4s" values="36;12;12;18;18;36;36" keySplines="0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1; 0.1 0.8 0.2 1" keyTimes="0;0.22;0.33;0.55;0.66;0.88;1" calcMode="spline" repeatCount="indefinite"/>
</circle>
</g>
</svg>
procedure TForm1.Button1Click(Sender: TObject);
var
RootNode: IXMLNode;
doc: IXmlDocument;
I: Integer;
dt: string;
begin
XMLDocument1.LoadFromFile('beer.svg');
XMLDocument1.Active := true;
RootNode := doc.ChildNodes.FindNode('svg');
for I := 0 to XMLDocument1.DocumentElement.ChildNodes.Count - 1 do
begin
dt := XMLDocument1.DocumentElement.ChildNodes[I].ChildNodes['animate'].Attributes['dur'].text;
Memo1.Lines.Add(dt);
end;
XMLDocument1.Active := False;
end;
