Inquirer
@Inquirer

Создание хорошо сформированного XSL для решения конкретной задачи

Проблема заключается в том, что момент простановки открывающего и закрывающего тегов строго не определён и зависит от значения соответствующего атрибута.

Задача


Имеется xml, грубо говоря, следующего вида:
<?xml version="1.0" encoding="utf-8"?>
<top>
    <person count="1" shift="3">
        содержимое
    </person>
...
    <person count="6" shift="endline">
        содержимое
    </person>
    <person count="7" shift="6">
        содержимое
    </person>
...
    <person count="9" shift="endline">
        содержимое
    </person>
</top>


На человеческом языке трансформация из данного вида в html-код выглядит так:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>
<xsl:template match='top'>
    <table class="scheme">
    <xsl:for-each select="person">
        <xsl:if test="@shift!=0">
            <tr><td class="fill"></td>
        </xsl:if>
        <xsl:if test="@shift=0"><tr></xsl:if>
        <td class="person"><p class="order"><xsl:value-of select="@count"/></p></td>
        <xsl:if test="@shift=endline"></tr></xsl:if>
    </xsl:for-each>
    </table>
</xsl:template>
</xsl:stylesheet>


Естественно, <xsl:if test="@shift=0"><tr></xsl:if><xsl:iftest="@shift=endline"></tr></xsl:if> не является корректным ни под каким предлогом.

Суть вопроса очевидна


Какова верная трансформация в данном случае, если максимальное количество ячеек в строке предопределено в скрипте-генераторе xml'а (в коде опущен момент заполнения пробелов в сетке таблицы)?

ОБН:

Образец иксэмэла и ожидаемый на выходе хатээмэл

<top>
    <person count="1" shift="4">
        <guest type="vip">
            <rank1>первая персоналия</rank1>
            <rank2>вторая персоналия</rank2>
            <full>2</full>
        </guest>
        <guest type="expected">
            <rank1>первая персоналия</rank1>
            <rank2>вторая персоналия</rank2>
            <rank3>третья персоналия</rank3>
            <full>7</full>
        </guest>
    </person>
    <person count="2" shift="endline">
        <guest type="important">
            <rank1>первая персоналия</rank1>
            <rank2>вторая персоналия</rank2>
            <rank3>третья персоналия</rank3>
            <full>3</full>
        </guest>
        <guest type="expected">
            <rank1>первая персоналия</rank1>
            <rank2>вторая персоналия</rank2>
            <rank3>третья персоналия</rank3>
            <full>5</full>
        </guest>
    </person>
    <person count="3" shift="2">
        <guest type="vip">
            <rank1>первая персоналия</rank1>
            <rank2>вторая персоналия</rank2>
            <rank3>третья персоналия</rank3>
            <full>6</full>
        </guest>
    </person>
    <person count="4" shift="endline">
        <guest type="vip">
            <rank1>первая персоналия</rank1>
            <rank2>вторая персоналия</rank2>
            <rank3>третья персоналия</rank3>
            <full>6</full>
        </guest>
        <guest type="important">
            <rank1>первая персоналия</rank1>
            <rank2>вторая персоналия</rank2>
            <rank3>третья персоналия</rank3>
            <full>3</full>
        </guest>
    </person>
    <person count="5" shift="0">
        <guest type="expected">
            <rank1>первая персоналия</rank1>
            <rank2>вторая персоналия</rank2>
            <rank3>третья персоналия</rank3>
            <full>7</full>
        </guest>
    </person>
    <person count="6">
        <guest type="vip">
            <rank1>первая персоналия</rank1>
            <rank2>вторая персоналия</rank2>
            <rank3>третья персоналия</rank3>
            <full>6</full>
        </guest>
        <guest type="expected">
            <rank1>первая персоналия</rank1>
            <rank2>вторая персоналия</rank2>
            <rank3>третья персоналия</rank3>
            <full>5</full>
        </guest>
    </person>
    <person count="7" shift="endline">
        <guest type="important">
            <rank1>первая персоналия</rank1>
            <rank2>вторая персоналия</rank2>
            <rank3>третья персоналия</rank3>
            <full>4</full>
        </guest>
        <guest type="expected">
            <rank1>первая персоналия</rank1>
            <rank2>вторая персоналия</rank2>
            <rank3>третья персоналия</rank3>
            <full>7</full>
        </guest>
    </person>
</top>

<table class="scheme">
<tr>
<td class="fill" colspan="4"></td>
<td class="person"><p class="order">1</p>
<div class="list">
<ol class="pv vip"><li>первая персоналия</li><li>вторая персоналия</li></ol><p class="total vip d1y">2</p>
<ol class="pv expected"><li>первая персоналия</li><li>вторая персоналия</li><li>третья персоналия</li></ol><p class="total expected d1y">7</p>
</div></td>
<td class="person"><p class="order">2</p>
<div class="list">
<ol class="pv important"><li>первая персоналия</li><li>вторая персоналия</li><li>третья персоналия</li></ol><p class="total important d2y">3</p>
<ol class="pv expected"><li>первая персоналия</li><li>вторая персоналия</li><li>третья персоналия</li></ol><p class="total expected d2y">5</p>
</div></td>
</tr>
<tr>
<td class="fill" colspan="2"></td>
<td class="person"><p class="order">3</p>
<div class="list">
<ol class="pv vip"><li>первая персоналия</li><li>вторая персоналия</li><li>третья персоналия</li></ol><p class="total vip d3y">6</p>
</div></td>
<td class="person"><p class="order">4</p>
<div class="list">
<ol class="pv vip"><li>первая персоналия</li><li>вторая персоналия</li><li>третья персоналия</li></ol><p class="total vip d4y">6</p>
<ol class="pv important"><li>первая персоналия</li><li>вторая персоналия</li><li>третья персоналия</li></ol><p class="total important d4y">3</p>
</div></td>
<td class="fill" colspan="2"></td>
</tr>
<tr>
<td class="person"><p class="order">5</p>
<div class="list">
ol class="pv expected"><li>первая персоналия</li><li>вторая персоналия</li><li>третья персоналия</li></ol><p class="total expected d5y">7</p>
</div></td>
<td class="person"><p class="order">6</p>
<div class="list">
<ol class="pv vip"><li>первая персоналия</li><li>вторая персоналия</li><li>третья персоналия</li></ol><p class="total vip d6y">6</p>
<ol class="pv expected"><li>первая персоналия</li><li>вторая персоналия</li><li>третья персоналия</li></ol><p class="total expected d6y">5</p>
</div></td>
<td class="person"><p class="order">7</p>
<div class="list">
<ol class="pv important"><li>первая персоналия</li><li>вторая персоналия</li><li>третья персоналия</li></ol><p class="total important d7y">4</p>
<ol class="pv expected"><li>первая персоналия</li><li>вторая персоналия</li><li>третья персоналия</li></ol><p class="total expected d7y">7</p>
</div></td>
<td class="fill" colspan="3"></td>
</tr>
</table>

  • Вопрос задан
  • 2483 просмотра
Решения вопроса 1
Решение вашей задачи выглядит вот так:
<xsl:if test="@shift=0"><xsl:text>&lt;tr&gt;</xsl:text></xsl:if>

и соответсвенно
<xsl:text>&lt;/tr&gt;</xsl:text>
для закрывания
Хотя я сейчас точно не помню, возможно надо будет добавить disable-output-escaping=«yes» в xsl:text

Но вообще говоря это не верное решение. Т.е. оно будет делать то, что вы хотите: добавлять открывающий и закрывающий тег tr в нужных местах, но так лучше не делать. Правильно делать так:
<?xml version="1.0" encoding="utf-8"?>
<top>
<persons-row>
    <person count="1">
        содержимое
    </person>
    <person count="6">
        содержимое
    </person>
</persons-row>
<persons-row>
    <person count="7">
        содержимое
    </person>
    <person count="9">
        содержимое
    </person>
</persons-row>
</top>


и xslt:
<xsl:for-each select="persons-row">
  <tr>
    <xsl:for-each select="person">
      <td><xsl:value-of select="." /></td>
    </xsl:for-each>
  </tr>
</xsl:for-each>

Соответсвенно надо еще следить чтобы во всех строках было одинаковое количество td, ну это я думаю вы придумаете как сделать :)
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@impass
мне кажется, у вас XML неправильно сформирован, поэтому приходится XSL так же коряво выпиливать под ситуацию

не очень понял назначение аттрибута shift

хотите формировать ряды у таблицы с нужным количеством заполненные ячеек — так группируйте данные для ячеек нужным образом ещё в XML'е
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы