зацикливание в XSLT - - PullRequest
       28

зацикливание в XSLT -

3 голосов
/ 17 декабря 2011

Мне нужно сделать следующий формат в XSLT. У меня есть цикл <xsl:for-each с 5 элементами (Text1, Text2 ... Text5), и мне нужно обернуть тег ul после каждых трех элементов. Любые предложения, пожалуйста?

<ul>
    <li>Text1</li>
    <li>Text2</li>
    <li>Text3</li>
</uL>
<ul>
    <li>Text4</li>
    <li>Text5</li>
</uL>

Ответы [ 2 ]

4 голосов
/ 17 декабря 2011

Хороший вопрос, + 1.

Это преобразование :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="thing" mode="inGrpoup">
  <li><xsl:value-of select="."/></li>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

при применении к следующему документу XML :

<things>
    <thing>1</thing>
    <thing>2</thing>
    <thing>3</thing>
    <thing>4</thing>
    <thing>5</thing>
    <thing>6</thing>
    <thing>7</thing>
    <thing>8</thing>
</things>

дает желаемый, правильный результат (вещи в группах по три подряд):

<ul>
   <li>1</li>
   <li>2</li>
   <li>3</li>
</ul>
<ul>
   <li>4</li>
   <li>5</li>
   <li>6</li>
</ul>
<ul>
   <li>7</li>
   <li>8</li>
</ul>

Объяснение

  1. Соответствие шаблону первое thing группы из трех thing элементов.

  2. Использование режимов для обработки группы thing элементов (иным способом, чем обработка начального запуска thing), после определения.

2 голосов
/ 17 декабря 2011

интересный вопрос.Ниже я изложил одно решение, которое использует <xsl:key> для идентификации каждой группы из трех, используя небольшую модульную арифметику.

Входной документ:

<TestDocument>
    <Element>Alpha</Element>
    <Element>Bravo</Element>
    <Element>Charlie</Element>
    <Element>Delta</Element>
    <Element>Echo</Element>
    <Element>Foxtrot</Element>
    <Element>Golf</Element>
    <Element>Hotel</Element>
</TestDocument>

Таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html"/>

    <!-- Declare a key to identify each group of 3 elements -->
    <xsl:key name="positionKey" match="/TestDocument/Element" use="floor((position() - 2) div 3)"/>
    <xsl:template match="/TestDocument">
        <html>
            <!-- Iterate over the first element in each group -->
            <xsl:for-each select="Element[(position() - 1) mod 3 = 0]">
                <ul>
                    <!-- Grab all elements from this group -->
                    <xsl:apply-templates select="key('positionKey', position()-1)"/>
                </ul>
            </xsl:for-each>
        </html>
    </xsl:template>

    <xsl:template match="Element">
        <li><xsl:value-of select="."/></li>
    </xsl:template>
</xsl:stylesheet>

Результаты:

<html>
    <ul>
        <li>Alpha</li>
        <li>Bravo</li>
        <li>Charlie</li>
    </ul>
    <ul>
        <li>Delta</li>
        <li>Echo</li>
        <li>Foxtrot</li>
    </ul>
    <ul>
        <li>Golf</li>
        <li>Hotel</li>
    </ul>
</html>
...