Переформатирование набора данных с использованием XSLT

#xml #xslt

#xml #xslt

Вопрос:

Итак, я никогда раньше не использовал XSLT, так что это, вероятно, очень простая проблема. По сути, моя работа заключается в создании видеороликов с разделами, и используемая нами программа генерирует XML-документ, содержащий пары временных кодов (где начинается глава в миллисекундах) и заголовок (название главы). Что я хочу сделать, так это преобразовать его в формат, понятный Final Cut Pro.

Программа генерирует данные в следующем формате:

 <marker time="27">
<label>Introduction</label>
</marker>
  

и Final Cut нуждается в этом формате (с временным кодом, преобразованным в кадры, иначе разделенным на 33,3).:

 <marker>
    <name>Introduction</name>
    <comment> amp;<CHAPTER>
    </comment>
    <color>
        <alpha>0</alpha>
        <red>127</red>
        <green>0</green>
        <blue>255</blue>
    </color>
    <in>27</in>
    <out>-1</out>
</marker>
  

Код, который я написал, является:

 <xsl:template match="/">
<xsl:for-each select="captionate/markers/marker">
<marker>
    <name><xsl:value-of select="label"/></name>
    <comment> amp;<CHAPTER>
    </comment>
    <color>
        <alpha>0</alpha>
        <red>127</red>
        <green>0</green>
        <blue>255</blue>
    </color>
    <in><xsl:value-of select="@time"/></in>
    <out>-1</out>
</marker>
</xsl:for-each>
</xsl:template>
  

но это не работает (я даже не совсем уверен, как это реализовать). Буду признателен за любую помощь!

Комментарии:

1. @Adam: что не работает? Я попробовал ваш код, и, похоже, он выдает почти в точности тот результат, который вы привели в качестве примера выше. Почти, потому что вместо CHAPTER> этого выдает CHAPTERamp;> . Это ваша проблема? Или у вас проблемы с разделением на 33,3? Или что еще?

2. Не вижу ничего неправильного во фрагментах, правильны ли ваши пространства имен, если таковые имеются? Вы пробовали //markers/marker ?

3. Вам лучше использовать XSLT-процессор, такой как Saxon.

4.@empo: amp;<CHAPTER> он хорошо сформирован.

5. @empo: неправда. > не обязательно экранировать в XML (за исключением редких ситуаций, связанных с разделами CDATA).

Ответ №1:

Я дополнил ваш образец данных (возможно, теперь он точно соответствует вашему?):

 <?xml version="1.0" encoding="utf-8"?>
<captionate>
<markers>
<marker time="27">
<label>Introduction</label>
</marker>
</markers>
</captionate>
  

Вот код снова, только минимальные изменения (показывает разделение):

 <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="/">
<xsl:for-each select="captionate/markers/marker">
<marker>
    <name><xsl:value-of select="label"/></name>
    <comment> amp;<CHAPTERamp;>
    </comment>
    <color>
        <alpha>0</alpha>
        <red>127</red>
        <green>0</green>
        <blue>255</blue>
    </color>
    <in><xsl:value-of select="@time div 33.33"/></in>
    <out>-1</out>
</marker>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
  

Выполнение этого через xsltproc дает ожидаемые результаты.