Генерация нескольких динамических строк HTML-таблицы с использованием XSLT - PullRequest
2 голосов
/ 23 мая 2011

Я хочу создавать строки в таблице динамически в зависимости от содержимого в XML.В приведенном ниже коде я пытаюсь создать строку (<tr>) с 5 столбцами.После заполнения 5 столбцов я хочу создать новую строку.

Строка может содержать только 5 столбцов в соответствии с приведенным ниже кодом.Если я применяю XSL к XML, я получаю сообщение об ошибке

XSLT compile.Начальный тег 'tr' в строке 574 не совпадает с конечным тегом 'xsl: when'.Строка 578, позиция 7.

570:<table>
571:    <xsl:for-each select="/alert/account_links/account_links_info">
572:                <xsl:choose>
573:                <xsl:when test="position() mod 5 = 1">
574:                    <tr>
575:                        <td>
576:                            <xsl:value-of select="account_id"/>
577:                        </td>                           
578:                </xsl:when>
579:                <xsl:when test="position() mod 5 = 0">
580:                    <td>
581:                        <xsl:value-of select="account_id"/>
582:                    </td>
583:                    </tr>
584:                </xsl:when>
585:                <xsl:otherwise>
586:                    <td>
587:                        <xsl:value-of select="account_id"/>
588:                    </td>
589:                </xsl:otherwise>
590:                </xsl:choose>
591:                </xsl:for-each>         
592:            </table>

Ввод XML:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<alert>
  <account_links>
    <account_links_info>
      <account_id>1</account_id>
    </account_links_info>
    <account_links_info>
      <account_id>2</account_id>
    </account_links_info>
    <account_links_info>
      <account_id>3</account_id>
    </account_links_info>
    <account_links_info>
      <account_id>4</account_id>
    </account_links_info>
    <account_links_info>
      <account_id>5</account_id>
    </account_links_info>
  </account_links>
</alert>

Может ли кто-нибудь помочь мне в этом?

Ответы [ 3 ]

7 голосов
/ 23 мая 2011

Попробуйте это решение:

<table>
       <xsl:for-each select="/alert/account_links/account_links_info[position()mod5=1]">
        <xsl:variable name = "current-pos" select="(position()-1) * 5+1"/>
        <tr>
        <xsl:for-each select="../account_links_info[position()&gt;=$current-pos and position() &lt; $current-pos+5]" >
            <td>
                <xsl:value-of select="account_id"/>
            </td>
        </xsl:for-each>
        </tr>           
       </xsl:for-each>         
</table>

(идея состоит в том, чтобы иметь внешний цикл для выхода <tr>, проходящий через каждый пятый account_links_info element, и внутренний цикл, заполняющий строки значениями account_id).

2 голосов
/ 24 мая 2011

Инструкции XSLT создают узлы в дереве результатов, а не лексические теги начала и конца. Вывод узла является одной операцией, вы не можете разделить его на две операции, записывая по половине узла каждая. Таким образом, ваше мышление должно быть «для каждых пяти узлов на входе я хочу создать узел на выходе», что естественно приводит к такой конструкции, как

<xsl:for-each select="*[position() mod 5 = 1]">

Не соблазняйтесь использованием для этого отключения-вывода-экранирования. Это яд. Это нарушает четкую архитектурную границу между механизмом преобразования и сериализованным, что означает, что ваша таблица стилей не может быть аккуратно развернута и повторно использована в произвольном конвейере (по этой причине она не будет работать в Firefox, если вам интересно в практических последствиях).

0 голосов
/ 23 мая 2011

Поскольку вы устанавливаете теги <tr> и </tr> в разных местах, вы должны вывести их в виде текста, чтобы сохранить его действительным XML для файла XSL.Кроме того, вы должны вывести тег </tr>, когда он является последним элементом в таблице или последняя строка не может быть закрыта:

<table>
  <xsl:for-each select="/alert/account_links/account_links_info">
    <xsl:if test="position()mod5=1">
      <xsl:text disable-output-escaping="yes">&lt;tr&gt;</xsl:text>          
    </xsl:if>
    <td>
      <xsl:value-of select="account_id"/>
    </td>
    <xsl:if test="position()mod5=0 or position()=last()">
      <xsl:text disable-output-escaping="yes">&lt;/tr&gt;</xsl:text>
    </xsl:if>        
  </xsl:for-each>
</table>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...