XSLT подсчитывает позицию и группирует предметы соответственно - PullRequest
0 голосов
/ 22 марта 2012

У меня есть некоторый входной XML, который

<collection>
    <content>
        <id>10</id>
        <type>xx</type>
        <title>xx</title>
        <quicklink>xx</quicklink>
        <teaser><p>xxx</p></teaser>
        <root>
            <thumb><img src="/xxx/xxx.jpg" /></thumb>
            <link>http://www.foo.com</link>
        </root>
        <startDate></startDate>
        <enddate></enddate>
        <hyperlink><a href="http://www.foo.com">some text</a></hyperlink>
    </content>
    <content>
        <id>10</id>
        <type>xx</type>
        <title>xx</title>
        <quicklink>xx</quicklink>
        <teaser><p>xxx</p></teaser>
        <root>
            <thumb><img src="/xxx/xxx.jpg" /></thumb>
            <link>http://www.foo.com</link>
        </root>
        <startDate></startDate>
        <enddate></enddate>
        <hyperlink><a href="http://www.foo.com">some text</a></hyperlink>
    </content>
    <content>
        <id>10</id>
        <type>xx</type>
        <title>xx</title>
        <quicklink>xx</quicklink>
        <teaser><p>xxx</p></teaser>
        <root>
            <thumb><img src="/xxx/xxx.jpg" /></thumb>
            <link>http://www.foo.com</link>
        </root>
        <startDate></startDate>
        <enddate></enddate>
        <hyperlink><a href="http://www.foo.com">some text</a></hyperlink>
    </content>
</collection>

XSLT записан для форматирования неупорядоченного списка, как показано ниже

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <ul id="case-study-icons">
      <xsl:for-each select="collection/content">
        <li>
          <a>
            <xsl:attribute name="href">
              <xsl:value-of select="Html/root/Link"/>
            </xsl:attribute>
            <xsl:attribute name="title">
              <xsl:value-of select="title"/>
            </xsl:attribute>
            <img>
              <xsl:attribute name="src">
                <xsl:value-of select="Html/root/thumb/img/@src"/>
              </xsl:attribute>
              <xsl:attribute name="alt">
                <xsl:value-of select="title"/>
              </xsl:attribute>
              <xsl:attribute name="width">92</xsl:attribute>
              <xsl:attribute name="height">46</xsl:attribute>
            </img>
          </a>
        </li>
      </xsl:for-each>
    </ul>
  </xsl:template>
</xsl:stylesheet>

Я хотел бы изменить это, чтобы иметь 3 ссылки на изображения внутриli and grounp every 3 item occurance into 3 image links groups wrapped with li`.Таким образом, в конце преобразования HTML должен выглядеть следующим образом:

<ul id="case-study-icons">
    <li>
        <a href="#"><img src="/foo.jpg" /></a>
        <a href="#"><img src="/foo.jpg" /></a>
        <a href="#"><img src="/foo.jpg" /></a>
    </li>
    <li>
        <a href="#"><img src="/foo.jpg" /></a>
        <a href="#"><img src="/foo.jpg" /></a>
        <a href="#"><img src="/foo.jpg" /></a>
    </li>
    <li>
        <a href="#"><img src="/foo.jpg" /></a>
        <a href="#"><img src="/foo.jpg" /></a>
        <a href="#"><img src="/foo.jpg" /></a>
    </li>
</ul>

Я пытался сделать это сам, используя position(), так как моя логика кажется не работает.Может кто-нибудь, пожалуйста, посмотрите?Большое спасибо заранее ..

Ответы [ 3 ]

3 голосов
/ 22 марта 2012

Выберите каждый третий Content элемент, затем запустите элемент li, затем выберите три элемента, которые вам нужны. Было не ясно, если ваши Content элементы были братьями и сестрами, поэтому я использовал following вместо following-sibling

  <xsl:for-each select="(Collection/Content)[position() mod 3 = 1]">
    <li>
       <xsl:for-each select=".|following::Content[position() &lt; 3]">
            <a href="{Html/root/Link}" title="{Title}">
               <img src="{Html/root/Thumb/img/@src}" alt="{Title}/>
             </a>
        </xsl:for-each>
   </li>
 </xsl:for-each>
0 голосов
/ 22 марта 2012

Возможно, вы захотите параметризовать количество элементов в группе, а не жестко кодировать 3 . Кроме того, это можно упростить, во-первых, избегая необходимости во вложенных xsl: for-each , а во-вторых, используя шаблоны значений атрибутов для записи атрибутов

Попробуйте этот XSLT, например

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:param name="itemsperlist" select="3" />

   <xsl:template match="/collection">
      <ul id="case-study-icons">
         <xsl:apply-templates select="content[(position() - 1) mod $itemsperlist = 0]" mode="first" />
      </ul>
   </xsl:template>

   <xsl:template match="content" mode="first">
      <li>
         <xsl:apply-templates select=".|following-sibling::content[position() &lt; $itemsperlist]" />
      </li>
   </xsl:template>

   <xsl:template match="content">
      <a href="{root/link}" title="{title}">
         <img src="{root/thumb/img/@src}" alt="{title}" width="92" height="46" />
      </a>
   </xsl:template>
</xsl:stylesheet>

Обратите внимание, что это решение будет работать, если вы измените 3 на 1 .

0 голосов
/ 22 марта 2012

Добрый Давид указал мне верное направление, и мне удалось прийти к правильному преобразованию.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <ul id="case-study-icons">
      <xsl:for-each select="(Collection/Content)[position() mod 3 = 1]">
        <li style="width:100px; float:left;">
        <xsl:for-each select=".|following-sibling::Content[position() &lt; 3]">
          <a>
            <xsl:attribute name="href">
              <xsl:value-of select="Html/root/Link"/>
            </xsl:attribute>
            <xsl:attribute name="title">
              <xsl:value-of select="Title"/>
            </xsl:attribute>
            <img>
              <xsl:attribute name="src">
                <xsl:value-of select="Html/root/Thumb/img/@src"/>
              </xsl:attribute>
              <xsl:attribute name="alt">
                <xsl:value-of select="Title"/>
              </xsl:attribute>
              <xsl:attribute name="width">92</xsl:attribute>
              <xsl:attribute name="height">46</xsl:attribute>
            </img>
          </a>
        </xsl:for-each>
        </li>
      </xsl:for-each>
      </ul>
  </xsl:template>
</xsl:stylesheet>
...