Выполнение вывода HTML в XSLT, если основано на позиции - PullRequest
1 голос
/ 11 ноября 2011

Я занят некоторыми вещами XSLT и хочу начинать новую строку каждые 3 пункта. Я подумал, что мог бы сделать оператор if и протестировать позицию 3, чтобы выяснить, являюсь ли я первой или последней ячейкой в ​​моей таблице.

Следующий оператор if работает, но Copernica (инструмент, в котором я использую XSLT) не принимает следующий XSLT. Причина в том, что <tr> не закрывается в операторе if.

Я ищу способ обработки потока товаров, разбитого на строки после 3 элементов.

<xsl:if test="position() mod 3 = 1">
<tr>
</xsl:if>

Ответы [ 2 ]

4 голосов
/ 11 ноября 2011

Я предполагаю, что вы использовали бы еще один <xsl:if/> позже в своем коде, чтобы закрыть <tr/>. К сожалению, хотя это было бы допустимо на другом языке программирования, это не может быть с xslt.

XSLT - это , а не a процедурный или императивный язык , поэтому не используйте его как единое целое. Вместо этого вы можете сделать что-то вроде этого:

<xsl:template match="element[position() mod 3 = 1]">
  <tr>
   <xsl:apply-templates mode="single" select=".|following-sibling::element[not(position() > 2)]"
   />
  </tr>
 </xsl:template>

 <xsl:template match="element" mode="single">
  <td>
    <!--your stuff between rows here-->
  </td>
 </xsl:template>

 <xsl:template match="element[not(position() mod 3 = 1)]"/>

Таким образом, это в основном создает tr каждые три строки и дополнительно вызывает другой шаблон для обработки элементов, которые находятся между этими строками. «element» должен быть элементом, который вы хотите обработать.

2 голосов
/ 11 ноября 2011

Если бы Коперника приняла этот XSLT, это было бы неправильно. XSLT - это XML, и XML должен быть строго иерархическим. Элемент <xsl:if> не может содержать начальный тег типа <tr> без соответствующего конечного тега </tr> в том же элементе <xsl:if>. Иными словами, таблица стилей XSLT не является потоком произвольной формы начальных и конечных тегов; это поток начальных и конечных тегов, которые выражают древовидную структуру узлов. <a> <b> </a> не выражает древовидную структуру, даже если у вас есть </b> позже. Думайте о начале / конце тегов как скобки:

(1 * [2 + 3)]

не грамматически.

@ FailedDev прав, что вы не можете рассматривать XSLT как процедурный язык программирования. Вы не можете предполагать, что элементы будут обработаны в определенном порядке. Вместо того, чтобы думать «мне нужно начинать новую строку каждые три элемента» (процедурную концепцию «один за другим»), вы должны понимать это как «мне нужно сгруппировать элементы в группы по три, причем строка содержит каждая группа. "

Я не могу представить себе лучшую реализацию этого, чем @ FailedDev в XSLT 1.0, поэтому я не буду предлагать ее. В XSLT 2.0 вы можете использовать

  <xsl:for-each-group group-starting-with="element[position() mod 3 = 1]">
    <tr>
      <xsl:apply-templates select="current-group()" />
    </tr>
  </xsl:for-each-group>

...

<xsl:template match="element">
   <!-- your stuff between rows here -->
</xsl:template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...