Ответы на этот вопрос показывают возможные пути решения проблемы:
xslt: Как я могу использовать xslt для создания таблицы с несколькими столбцами и строками?
РЕДАКТИРОВАТЬ: Решение, которое включает в себя методы, представленные в связанном вопросе, следует.
Я предполагаю:
- your
@row
и @col
представляют собой инкрементные числа, которые определяют положение записи в таблице, и они не могут действительно содержать строку "n"
. Как таковые они не уникальны во всем документе, что делает их непригодными в качестве атрибутов HTML @id
. Я заменил их @title
атрибутами в моем выводе.
- нет неявных пустых строк (пробелы в непрерывности
@row
не приведут к пустым строкам), только неявные пустые ячейки.
- каждая комбинация
@row
и @col
уникальна.
Это преобразование XSLT 1.0:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<!-- prepare some keys for later use -->
<xsl:key name="kRecordsByRow" match="record" use="@row" />
<xsl:key name="kRecordsByPos" match="record" use="concat(@row, ',', @col)" />
<!-- find out the highest @col number -->
<xsl:variable name="vMaxCol">
<xsl:for-each select="/root/record">
<xsl:sort select="@col" data-type="number" order="descending" />
<xsl:if test="position() = 1">
<xsl:value-of select="@col" />
</xsl:if>
</xsl:for-each>
</xsl:variable>
<!-- select the <record>s that are the first in their rows -->
<xsl:variable name="vRows" select="
/root/record[
generate-id()
=
generate-id(key('kRecordsByRow', @row)[1])
]
" />
<!-- output basic table structure -->
<xsl:template match="/root">
<table>
<xsl:for-each select="$vRows">
<xsl:sort select="@row" data-type="number" />
<tr title="{@row}">
<xsl:call-template name="td" />
</tr>
</xsl:for-each>
</table>
</xsl:template>
<!-- output the right number of <td>s in each row, empty or not -->
<xsl:template name="td">
<xsl:param name="col" select="1" />
<td title="{$col}">
<xsl:value-of select="key('kRecordsByPos', concat(@row, ',', $col))/@val" />
</td>
<xsl:if test="$col < $vMaxCol">
<xsl:call-template name="td">
<xsl:with-param name="col" select="$col + 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
… применительно к этому (слегка измененному) входу:
<root>
<record row="1" col="1" val="1" />
<record row="1" col="2" val="2" />
<record row="1" col="3" val="3" />
<record row="1" col="4" val="4" />
<record row="2" col="1" val="5" />
<record row="2" col="3" val="6" />
<record row="2" col="4" val="7" />
<record row="3" col="2" val="8" />
<record row="3" col="3" val="9" />
<record row="3" col="4" val="10" />
</root>
... производит:
<table>
<tr title="1">
<td title="1">1</td>
<td title="2">2</td>
<td title="3">3</td>
<td title="4">4</td>
</tr>
<tr title="2">
<td title="1">5</td>
<td title="2"></td>
<td title="3">6</td>
<td title="4">7</td>
</tr>
<tr title="3">
<td title="1"></td>
<td title="2">8</td>
<td title="3">9</td>
<td title="4">10</td>
</tr>
</table>
- Muenchian группировка используется для выбора первых
<record>
с каждой @row
группы
- и
<xsl:key>
используется для точного определения записи по ее положению
- рекурсия используется для создания согласованного набора
<td>
с, независимо от фактического существования <record>
в названной позиции