2017-01-27 14 views
-1

множество узлов Учитывая следующий XML:XSLT 1.0: Фильтр, Сортировка и страниц в

<A> 
    <Photos> 
    <Photo> 
     <PhotoID>142</PhotoID> 
     <PhotoTitle>A</PhotoTitle> 
     <Comment /> 
    </Photo> 
    <Photo> 
     <PhotoID>143</PhotoID> 
     <PhotoTitle>B</PhotoTitle> 
     <Comment /> 
    </Photo> 
    <Photo> 
     <PhotoID>144</PhotoID> 
     <PhotoTitle>C</PhotoTitle> 
     <Comment /> 
    </Photo> 
    <Photo> 
     <PhotoID>145</PhotoID> 
     <PhotoTitle>D</PhotoTitle> 
     <Comment /> 
    </Photo> 
    <Photo> 
     <PhotoID>146</PhotoID> 
     <PhotoTitle>E</PhotoTitle> 
     <Comment /> 
    </Photo> 
    <Photo> 
     <PhotoID>195</PhotoID> 
     <PhotoTitle>F</PhotoTitle> 
     <Comment>Foo</Comment> 
    </Photo> 
    <Photo> 
     <PhotoID>196</PhotoID> 
     <PhotoTitle>G</PhotoTitle> 
     <Comment>Bar</Comment> 
    </Photo> 
    <Photo> 
     <PhotoID>197</PhotoID> 
     <PhotoTitle>H</PhotoTitle> 
     <Comment>Baz</Comment> 
    </Photo> 
    <Photo> 
     <PhotoID>199</PhotoID> 
     <PhotoTitle>F</PhotoTitle> 
     <Comment>qux</Comment> 
    </Photo> 
    </Photos> 
</A> 

Я хотел бы получить выход HTML, подобный следующему:

<div id="photoPage" class="page"> 
    <!-- Page Header Goes Here --> 
    <div> 
     <h2>Page Title Goes Here</h2> 
     <div class="photoBox"> 
      <!-- Image URL goes here --> 
      <div> 
       <div> 
        F 
       </div> 
       <div> 
        Foo 
       </div> 
      </div> 
     </div> 
     <div class="photoBox"> 
      <!-- Image URL goes here --> 
      <div> 
       <div> 
        F 
       </div> 
       <div> 
        Qux 
       </div> 
      </div> 
     </div> 
    </div> 
    <!-- Page Footer Goes Here --> 
</div> 
<div id="photoPage" class="page"> 
    <!-- Page Header Goes Here --> 
    <div> 
     <h2>Page Title Goes Here</h2> 
     <div class="photoBox"> 
      <!-- Image URL goes here --> 
      <div> 
       <div> 
        G 
       </div> 
       <div> 
        Bar 
       </div> 
      </div> 
     </div> 
     <div class="photoBox"> 
      <!-- Image URL goes here --> 
      <div> 
       <div> 
        H 
       </div> 
       <div> 
        Baz 
       </div> 
      </div> 
     </div> 
    </div> 
    <!-- Page Footer Goes Here --> 
</div> 

В целом, я Я пытаюсь отфильтровать фотографии, которые включают только те, которые имеют название «F», «G» или «H», отсортированы по названию и идентификатору, а затем разбиваются на группы по два. Я смог выполнить фильтрацию и сортировку, но не пейджинг или пейджинг, но не фильтрацию и сортировку, но я не смог сделать все три.

Для справки, я пытаюсь выполнить подкачку, похожую на this solution.

Вот такой подход не работает:

<xsl:template name="Photos">  
    <xsl:copy> 
     <xsl:apply-templates select="//Photos[Photo/PhotoTitle = 'F' or Photo/PhotoTitle = 'G' or Photo/PhotoTitle = 'H']"> 
     <xsl:sort select="PhotoTitle"/> 
     <xsl:sort select="PhotoID"/> 
     </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="Photos"> 
    <xsl:param name="pageSize" select="2"></xsl:param> 
    <xsl:for-each select="//Photos/Photo[position() mod $pageSize = 1]"> 
     <div id="photoPage" class="page"> 
     <div> 
      <h2>Title</h2> 
      <xsl:apply-templates select="self::*|following-sibling::*[position() &lt; $pageSize]"> 
      </xsl:apply-templates> 
     </div> 
     </div> 
    </xsl:for-each> 
</xsl:template> 

<xsl:template match="Photo"> 
    <div class="photoBox"> 
     <!-- img tag --> 
     <div> 
     <div> 
      <xsl:value-of select="./PhotoTitle"/> 
     </div> 
     <div> 
      <xsl:value-of select="./Comment"/> 
     </div> 
     </div> 
    </div> 
</xsl:template> 

Идея заключается в том, что я явно вызвать первый шаблон, который должен фильтровать и сортировать фотографии элемента, применяя второй шаблон, который расщепляет и оборачивает фотоэлементы на две страницы и применяет третий шаблон, который выводит и отдельную фотографию.

Результаты, полученные в настоящее время, не фильтруются и не сортируются, а разделяются соответствующим образом. Я подозреваю, что это связано с тем, что шаблон Фотографии совпадает с шаблоном, который я явно вызываю.

+2

Почему вы не публикуете ваш попытаемся, чтобы мы могли исправить это, вместо того, чтобы писать код для вас с нуля. - P.S. Вы говорите, что вам нужны группы из трех человек, но я вижу группы из двух человек. –

ответ

1

Идея заключается в том, что я явно вызвать первый шаблон

Я не вижу такой вызова в коде вы публикуемый. И второй шаблон делает xsl:for-each, выбрав всеPhoto s, без фильтрации по Title.

Другая проблема с вашим подходом заключается в том, что вы не можете использовать ось following-sibling без копирования сначала фильтрованных узлов (и, поскольку вы используете XSLT 1.0, преобразование полученного фрагмента дерева в набор узлов, обрабатываться во втором проходе).

У вас также есть несколько синтаксических ошибок.

Попробуйте это в качестве отправной точки:

XSLT 1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:exsl="http://exslt.org/common" 
extension-element-prefixes="exsl"> 
<xsl:strip-space elements="*"/> 

<xsl:template match="A"> 
    <html> 
     <body> 
      <xsl:apply-templates/> 
     </body> 
    </html> 
</xsl:template> 

<xsl:template match="Photos"> 
    <xsl:param name="pageSize" select="2"/> 
    <!-- first pass --> 
    <xsl:variable name="photos"> 
     <xsl:for-each select="Photo[PhotoTitle = 'F' or PhotoTitle = 'G' or PhotoTitle = 'H']"> 
      <xsl:sort select="PhotoTitle"/> 
      <xsl:sort select="PhotoID" data-type="number"/> 
      <xsl:copy-of select="."/> 
     </xsl:for-each> 
    </xsl:variable> 
    <!-- output --> 
    <xsl:for-each select="exsl:node-set($photos)/Photo[position() mod $pageSize = 1]"> 
     <div id="photoPage" class="page"> 
      <div> 
       <h2>Title</h2> 
       <xsl:apply-templates select=". | following-sibling::Photo[position() &lt; $pageSize]"/> 
      </div> 
     </div> 
     </xsl:for-each> 
</xsl:template> 

<xsl:template match="Photo"> 
    <div class="photoBox"> 
     <!-- img tag --> 
     <div> 
     <div> 
      <xsl:value-of select="PhotoTitle"/> 
     </div> 
     <div> 
      <xsl:value-of select="Comment"/> 
     </div> 
     </div> 
    </div> 
</xsl:template> 

</xsl:stylesheet> 

Применительно к вашему примеру вход, то результат будет:

<html> 
    <body> 
     <div id="photoPage" class="page"> 
     <div> 
      <h2>Title</h2> 
      <div class="photoBox"> 
       <div> 
        <div>F</div> 
        <div>Foo</div> 
       </div> 
      </div> 
      <div class="photoBox"> 
       <div> 
        <div>F</div> 
        <div>qux</div> 
       </div> 
      </div> 
     </div> 
     </div> 
     <div id="photoPage" class="page"> 
     <div> 
      <h2>Title</h2> 
      <div class="photoBox"> 
       <div> 
        <div>G</div> 
        <div>Bar</div> 
       </div> 
      </div> 
      <div class="photoBox"> 
       <div> 
        <div>H</div> 
        <div>Baz</div> 
       </div> 
      </div> 
     </div> 
     </div> 
    </body> 
</html>