Для определенного формата вывода (не HTML-подобный), мне нужно, чтобы преобразовать HTML таблицу в «квадрате» таблицу, где каждый colspan
и rowspan
не только указанная в родительской ячейки, но также следует правильное количество пустых ячеек.Преобразовать
Например, простой HTML таблицы
<table>
<tr>
<th>test</th>
<th colspan="2">span 1/2</th>
<th colspan="3">span 2/2</th>
</tr>
<tr>
<td>col 1</td>
<td>col 2</td>
<td>col 3</td>
<td>col 4</td>
<td>col 5</td>
<td>col 6</td>
</tr>
</table>
должны быть переведены на
<table>
<tr>
<th>test</th>
<th colspan="2">span 1/2</th>
<th /> <!-- < empty cell added -->
<th colspan="3">span 2/2</th>
<th /> <!-- < empty cell added -->
</tr>
..
(примечание: формат вывода использует совершенно иной синтаксис, это только для ясности!)
и, соответственно, ряды должны распространяться до следующих <tr>
линий:
<table><tr><td rowspan="3" /><td rowspan="2" /><td /></tr>
<tr><td>data</td></tr>
<tr><td>data</td><td>data</td></tr>
</table>
, который должен выйти в
<table>
<tr><td /><td /><td /></tr>
<tr><td /><td /><td>data</td></tr> <!-- 2 empty cells added -->
<tr><td /><td>data</td><td>data</td></tr> <!-- 1 empty cell added -->
<table>
Обработка colspan
проста:
<xsl:template name="add-empty">
<xsl:param name="repeat" />
<xsl:if test="$repeat > 1">
<td class="empty" />
<xsl:call-template name="add-empty">
<xsl:with-param name="repeat" select="$repeat - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="th|td">
<td>
<xsl:apply-templates />
</td>
<xsl:if test="@colspan">
<xsl:call-template name="add-empty">
<xsl:with-param name="repeat" select="@colspan" />
</xsl:call-template>
</xsl:if>
</xsl:template>
Это добавит одного th
или td
, проверить каждого из них colspan
и вставьте столько пустых ячеек при необходимости с рекурсивный вызов шаблону add-empty
. Атрибут класса empty
предназначен только для отладки.
Проблема в rowspan
с. Для правильной работы необходимо сканировать более каждыеtr
и сохранить количество столбцов, которые должны быть пустыми. Это итерация будет что-то вроде
<xsl:if test="position() > 1">
<xsl:variable name="currentRow" select="position()" />
<xsl:for-each select="../tr[position() < $currentRow]">
<xsl:message>testing <xsl:value-of select="." /></xsl:message>
</xsl:for-each>
</xsl:if>
- это не обязательно должны быть вызваны в первом ряду, потому что только colspan
сек необходимость добавления. Таким образом, вопрос двояка: как бы я создал список наборов ячеек, чтобы добавить правильный набор для текущей строки ? И с таким списком, как я могу перебирать и этот список (до тех пор, пока общее количество столбцов в таблице) и элементов каждой строки th|td
?
Последнее является проблемой, потому что я могу перебрать либо клетка установить, используя нечто вроде
<xsl:for-each select="1 to string-length(cell-set)">
<xsl:if test="substring($cell-set, ., 1) = 'E'>
.. empty ..
...
</xsl:for-each>
(если cell-set
это строка), или над «текущим» tr
содержимого с использованием
<xsl:for-each select="th|td">
..
В этом случае нет прямого отношения к содержанию cell-set
. С первым, я не знаю, какой индекс td|th
вставить, со вторым я не знаю, когда вставить пробел.
Как вы, кажется, перешли на XSLT 2.0 вы можете проверить http://andrewjwelch.com/code/xslt/ table/table-normalization.html как идея, он копирует существующую ячейку вместо добавления пустой, но не такой, какой должен сделать алгоритм, если я не ошибаюсь в отношении ваших требований. –
@MartinHonnen: Я не так много «переключился», как немного опоздал, понял, что мне лучше указать, что :) - задача кажется достаточно сложной, даже * с функциями * 2.0. Посмотрите на ссылку и ваш ответ a.s.a.p. (Ah - например, 'for-each select =" 1 to @colspan "вместо моего собственного рекурсивного шаблона в 1.0 ... аккуратно!) – usr2564301
@RadLexus Посмотрите, поможет ли это: http://stackoverflow.com/a/27217608/3016153 –