При попытке реализовать шаблон «Двухэтапный просмотр», как описано Мартином Фаулером, у меня возникли проблемы с тем, чтобы работать с раскраской чередующейся строки таблицы HTML. Это использует функцию XSLT position()
. Вы можете увидеть шаблон XSLT для table/row
ниже. Однако в выводе атрибут bgcolor
элемента tr
всегда равен "linen"
, что указывает на то, что значение position()
не изменяется при переходе по table/row
элементам. Почему это должно быть?Функция позиции XSLT() не работает, как ожидалось, в двухэтапном представлении
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="screen">
<html>
<body bgcolor="white">
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="title">
<h1>
<xsl:apply-templates/>
</h1>
</xsl:template>
<xsl:template match="field">
<p><b><xsl:value-of select="@label"/>: </b><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="table">
<table><xsl:apply-templates/></table>
</xsl:template>
<xsl:template match="table/row">
<xsl:variable name="bgcolor">
<xsl:choose>
<xsl:when test="(position() mod 2) = 0">linen</xsl:when>
<xsl:otherwise>white</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<tr bgcolor="{$bgcolor}"><xsl:apply-templates/></tr>
</xsl:template>
<xsl:template match="table/row/cell">
<td><xsl:apply-templates/></td>
</xsl:template>
</xsl:stylesheet>
Входной XML:
<?xml version="1.0"?>
<screen>
<title>Dissociation</title>
<field label="Artist">Dillinger Escape Plan</field>
<table>
<row>
<cell>Limerent Death</cell>
<cell>4:06</cell>
</row>
<row>
<cell>Symptom Of Terminal Illness</cell>
<cell>4:03</cell>
</row>
<row>
<cell>Wanting Not So Much To As To</cell>
<cell>5:23</cell>
</row>
</table>
</screen>
Выходной HTML:
<html><body bgcolor="white">
<h1>Dissociation</h1>
<p><b>Artist: </b>Dillinger Escape Plan</p>
<table>
<tr bgcolor="linen">
<td>Limerent Death</td>
<td>4:06</td>
</tr>
<tr bgcolor="linen">
<td>Symptom Of Terminal Illness</td>
<td>4:03</td>
</tr>
<tr bgcolor="linen">
<td>Wanting Not So Much To As To</td>
<td>5:23</td>
</tr>
</table>
</body></html>
Спасибо, это сработало. Но я действительно не понимаю, почему, конечно, '' будет препятствовать оценке 'position()' test на элементах, отличных от строки? В чем разница между использованием 'match' (которое не работает) и использованием' select = '(что работает)? –
amoe
С помощью ' ' (поскольку это сокращенное выражение для ' '), вы выбираете все дочерние узлы для обработки, и таким образом у вас есть различные узлы (XSLT 1.0) или последовательность (XSLT 2.0) обрабатываются по сравнению с ' '. Внутри всех дочерних узлов определенный элемент 'row' имеет другую позицию по сравнению с поиском только элементов' row', в частности, с форматированным XML, где между узлами элементов есть текстовые узлы с пробелами. Подробнее см. Https://www.w3.org/TR/xslt#section-Applying-Template-Rules. –
Соответственно https://www.w3.org/TR/xslt20/#applying-templates: «Правило, которое соответствует N-му узлу в отсортированной последовательности, оценивается с этим узлом как элемент контекста, а N - как контекстная позиция, и с длиной сортированной последовательности, как размер контекста ». –