Динамическая вставка тегов XSLT для элементов маркированного списка - PullRequest
0 голосов
/ 26 октября 2018

Я только начал изучать XSLT и просматривал примеры W3school для решения новой задачи, которую дал мне мой работодатель.

У меня есть несколько файлов, которые мне нужно преобразовать с помощью структур XML следующим образом.

     <tablecell bgcolor='white'>
<pardef id='16' leftmargin='0.2757in' list='bullet' keepwithnext='true' keeptogether='true'/>
        <par def='34'>
            <run>
                <font size='8pt' name='Verdana' pitch='variable' truetype='true'
     familyid='20' color='navy'/>Data in bullet point 1</run>
        </par>
        <par def='34'>
            <run>
                <font size='8pt' name='Verdana' pitch='variable' truetype='true'
     familyid='20' color='navy'/>Data in bullet point 2</run>
        </par>
        <par def='34'>
            <run>
                <font size='8pt' name='Verdana' pitch='variable' truetype='true'
     familyid='20' color='navy'/>Data in bullet point 3</run>
        </par>
        <par def='34'>
            <run>
                <font size='8pt' name='Verdana' pitch='variable' truetype='true'
     familyid='20' color='navy'/>Data in bullet point 4</run>
        </par>
    </tablecell>

То, что у меня есть для моего XSL для обработки XML, выглядит следующим образом.

    <xsl:template match="tablecell">
            <td>
                <xsl:copy-of select="@colspan" />
                <!--<xsl:value-of select="."/> -->
                <xsl:apply-templates select="table" />
                <xsl:apply-templates select="section" />
                <xsl:apply-templates select="par" />
                <xsl:apply-templates select="pardef" />
            </td>
    </xsl:template>

<xsl:template match="pardef">
        <xsl:if test="@list='bullet'">
            <ul>
                <xsl:apply-templates/>
         </xsl:if>
    </xsl:template>

    <xsl:template match="par">
            <p>
                <xsl:apply-templates select="run" />
            </p>
    </xsl:template>

    <xsl:template match="run">
            <li>
                <xsl:apply-templates select="run" />
            </li>
    </xsl:template>

Проблема, с которой я столкнулся, заключается в том, что я не уверен, как лучше всего динамически вставить закрывающий тег </ul> после последнего элемента <run>, чтобы создать точки маркера. На практике в моих XML-файлах может быть любое количество тегов <run> для преобразования.

Это где мне нужно что-то сделать с переменной и подсчитать количество элементов, а затем выполнить некоторую обработку на основе этой переменной?

Другая ситуация, для которой мне нужно руководство по организации питания, заключается в том, что теги <run> должны быть окружены тегами <li>, только если они находятся в структуре pardef / par, где элемент pardef имеет атрибут list = = bullet. .

Это вывод, который я пытаюсь достичь.

<p>
    <ul>
        <li>Data in bullet point 1</li>
        <li>Data in bullet point 2</li>
        <li>Data in bullet point 3</li>
        <li>Data in bullet point 4</li>
    </ul>  
</p>

Если бы вы могли указать мне правильное направление для двух упомянутых выше запросов, мы будем благодарны.

Приветствия


Не уверен, как продолжить этот существующий поток с большим количеством фрагментов кода, кроме редактирования существующего потока. Если бы вы могли дать мне знать, как это сделать, было бы здорово.

Спасибо всем, кто помог с этой проблемой до сих пор. Кто-то ответил на этот пост ранее с идеей использовать режимы, которые помогли мне продвинуться дальше. Вопрос, который у меня возник сейчас, заключается в следующей ситуации: если с атрибутом def = 16 встречаются теги <par>, я хочу, чтобы он использовал шаблон mode = 'шестнадцать', в противном случае используйте шаблон общего базового номинала, который очень просто использует <p> </p> теги. Как этого добиться? Прямо сейчас я думаю об использовании оператора if, но будет ли это наилучшим практическим способом сделать это?

Кроме того, означает ли приведенный ниже код, что элементы <par> потенциально обрабатываются дважды?

<xsl:template match="tablecell">
        <td>
            <!-- <xsl:copy-of select="@colspan" /> -->
            <xsl:apply-templates select="par" />
            <xsl:apply-templates select="table" />
            <xsl:apply-templates select="section" />

            <!-- Apply to par elements where attribute def=16 -->   
            <xsl:apply-templates select="par[@def='16']" mode='sixteen' />
        </td>
    </xsl:template>

    <!-- Template for par elements where attribute def=16 -->
    <xsl:template match="par" mode='sixteen'>
        <ul>
            <!-- Apply to any table elements -->    
            <xsl:apply-templates select="run" mode='bullet' />
        </ul>
    </xsl:template>

Это моя попытка, но я не уверен, что она правильная или лучшая.

  <xsl:template match="tablecell">
        <td>
            <xsl:choose>
                <xsl:when test="par[@def='16']">
                    <!-- Apply to par elements where attribute def=16 -->   
                    <xsl:apply-templates select="par[@def='16']" mode='sixteen' />

                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="par" />

                </xsl:otherwise>


            </xsl:choose>
<xsl:apply-templates select="table" />
                <xsl:apply-templates select="section" />
        </td>
    </xsl:template>

1 Ответ

0 голосов
/ 26 октября 2018

Ключевым моментом, который вам не хватает, является то, что XSLT не создает начальный и конечный теги в выходных данных, он создает дерево узлов.Вы не можете написать половину узла в дереве.«Литеральный элемент результата», такой как <ul> XXX </ul>, представляет собой одну инструкцию, которая (a) оценивает XXX для создания некоторого контента и (b) создает узел элемента UL, к которому этот контент присоединен.Вы должны думать о <ul></ul> как об одной инструкции, которая создает узел, а не как инструкцию, которая создает начальный тег, за которой следует инструкция, которая создает конечный тег.

Ваша проблема - это проблема классической позиционной группировки.Фактически это один из примеров, используемых в спецификации XSLT для инструкции xsl:for-each-group: найдите «Пример: группировка чередующихся последовательностей элементов» в https://www.w3.org/TR/xslt-30/#element-for-each-group.Обратите внимание, что эта инструкция требует XSLT 2.0 или XSLT 3.0.Во многих средах процессор XSLT по умолчанию все еще поддерживает только XSLT 1.0.Гораздо сложнее решить эту проблему в версии 1.0 (это не невозможно, но это серьезная проблема для новичка в языке).Поэтому убедитесь, что вы используете процессор с поддержкой 2.0 или 3.0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...