2013-05-16 4 views
0

У меня есть следующий список предметов.Элементы группировки XSLT по количеству

<items> 
    <item type="Type1">Item1</item> 
    <item type="Type2">Item2<item> 
    <item type="Type2">Item3<item> 
    <item type="Type3">Item4<item> 
    <item type="Type3">Item5<item> 
    <item type="Type1">Item6<item> 
    <item type="Type3">Item7<item> 
    <item type="Type1">Item8<item> 
    <item type="Type2">Item9<item> 
    <item type="Type1">Item10<item> 
<items> 

У меня возникли проблемы выясняя XSLT, необходимый, так что выше отображаются в группах Type1 (x1), Type2 (x2), Type3 (x4), где подсчеты число в скобках или Меньше. Другими словами, цель состоит в том, чтобы создать повторяющийся шаблон: следующий элемент Type1, если какой-либо из них останется, то следующие два элемента Type2 или меньше, если осталось меньше двух, а затем следующие четыре элемента Type3 или меньше, если меньше чем четыре остаются.

Так что желаемый результат будет выглядеть так, как показано ниже:

<div class="Items"> 
    <div class="Type1">Item1</div> 
    <div class="Type2">Item2</div> 
    <div class="Type2">Item3</div> 
    <div class="Type3">Item4</div> 
    <div class="Type3">Item5</div> 
    <div class="Type3">Item7</div> 
    <div class="Type1">Item6</div> 
    <div class="Type2">Item9</div> 
    <div class="Type1">Item8</div> 
    <div class="Type1">Item10</div> 
</div> 

Из вышеприведенного вывода, вы можете увидеть, что порядок изменился. то есть < = 1 Тип 1, затем < = 2 Тип2, затем < = 4 Тип3, и этот шаблон повторяется. Я полагаю, что элементы нужно будет сгруппировать в описанный образец и повторить до полного списка, если элементы исчерпаны. Надеюсь, у меня есть смысл.

Может ли кто-нибудь предоставить требуемый XSLT или некоторые указатели, пожалуйста?

Thanks, John.

+1

вы можете добавить немного больше контекста, я могу» не видите, как выстраивается вывод? Они не группируются или не упорядочиваются по классу, и кажется, что кроме переключения элементов 6 и 7, и 8 и 9, вывод одинаков. –

+0

Как и в настоящее время сформулировано, это не настоящий вопрос - трудно понять необходимые (если есть) правила, которые должно выполнить преобразование. Пожалуйста, отредактируйте и объясните. –

+0

Привет, ребята, я редактировал сообщение. Спасибо, что посмотрели на это. –

ответ

0

Пожалуйста, дайте этот водоворот:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:key name="kType2Group" match="item[@type = 'Type2']" 
      use="floor(count(preceding-sibling::item[@type = 'Type2']) div 2) + 1"/> 
    <xsl:key name="kType3Group" match="item[@type = 'Type3']" 
      use="floor(count(preceding-sibling::item[@type = 'Type3']) div 4) + 1"/> 

    <xsl:template match="@* | node()" name="Copy"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/*"> 
    <xsl:copy> 
     <xsl:apply-templates select="item[@type = 'Type1']" /> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="item[@type = 'Type1']"> 
    <xsl:call-template name="Copy" /> 
    <xsl:apply-templates select="key('kType2Group', position())" /> 
    <xsl:apply-templates select="key('kType3Group', position())" /> 
    </xsl:template> 
</xsl:stylesheet> 

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

<items> 
    <item type="Type1">Item1</item> 
    <item type="Type2">Item2</item> 
    <item type="Type2">Item3</item> 
    <item type="Type3">Item4</item> 
    <item type="Type3">Item5</item> 
    <item type="Type3">Item7</item> 
    <item type="Type1">Item6</item> 
    <item type="Type2">Item9</item> 
    <item type="Type1">Item8</item> 
    <item type="Type1">Item10</item> 
</items> 

Ключи в этом случае используются для разделения TYPE2 и TYPE3 элементы в групп, чтобы их можно было получить по их номеру группы (1, 2, 3 и т. д.), логика для определения номеров групп - подсчитать количество предшествующих элементов одного и того же типа, делить это число на количество элементов в каждой группе, округлите и добавьте один. Так, например, этот расчет, выполненный для первых четырех Type2, будет следующим:

floor(0 div 2) + 1 = floor(0) + 1 = 0 + 1 = 1 
floor(1 div 2) + 1 = floor(0.5) + 1 = 0 + 1 = 1 
floor(2 div 2) + 1 = floor(1) + 1 = 1 + 1 = 2 
floor(3 div 2) + 1 = floor(1.5) + 1 = 1 + 1 = 2 

и так далее.

Общая логика XSLT является:

  • Match корневой элемент, скопируйте его, и применять шаблоны ко всем элементам Type1.
  • Шаблон для предметов Type1:
    • Копирует сам предмет.
    • использует ключ, чтобы применить шаблоны к пунктам TYPE2 в своей группе (position() будет 1 для первого элемента Type1, 2 для второго, и так далее.
    • использует ключ, чтобы применить шаблоны к элементам TYPE3 в его группа
  • Первый шаблон, шаблон стиля, делает работу копирования ничего такого, что не имеет какой-либо другой шаблон, чтобы соответствовать его.
+0

Спасибо @JLRishe. Это сработало, когда я положил его через http://xslttest.appspot.com/. Как вы, наверное, можете сказать, я не очень хорошо разбираюсь в XSLT. Было бы здорово, если бы вы могли дать мне небольшое решение по вашему решению? Особенно вокруг использования ключей. –

+0

Добавлена ​​некоторая проработка выше. – JLRishe

+0

Удивительный! Это очень мощный материал. Я попытаюсь применить это к сценарию, который у меня есть. Еще раз спасибо. –

Смежные вопросы