2010-03-08 3 views
2

У меня возникли проблемы, чтобы выяснить способ группировки элементов xslt 1.0. У меня есть исходный XML, подобный приведенному ниже:Группировка каждые 3 элемента в xslt 1.0

<client name="client A"> 
    <project name = "project A1"/> 
    <project name = "project A2"/> 
    <project name = "project A3"/> 
    <project name = "project A4"/> 
</client> 
<client name="client B"> 
    <project name = "project B1"/> 
    <project name = "project B2"/> 
</client> 
<client name="client C"> 
    <project name = "project C1"/> 
    <project name = "project C2"/> 
    <project name = "project C3"/> 
</client> 

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

<boundle> 
    <project name="project A1"> 
    <project name="project A2"> 
    <project name="project A3"> 
</boundle> 
<boundle> 
    <project name="project A4"> 
    <project name="project B1"> 
    <project name="project B2"> 
</boundle> 
<boundle> 
    <project name="project C1"> 
    <project name="project C2"> 
    <project name="project C3"> 
</boundle> 

В настоящее время для этого я использую, чтобы открыть тег ограничения и закрыть его позже. Можете ли вы подумать о каком-либо лучшем решении?

ответ

4

Не требуется группировка.

<xsl:param name="perGroup" select="3" /> 

<xsl:variable name="allProjects" select="/client/project" /> 

<xsl:template match="/"> 
    <xsl:apply-templates select="$allProjects" mode="counted" /> 
</xsl:template> 

<xsl:template match="project" mode="counted"> 
    <xsl:if test="position() mod $perGroup = 1"> 
    <xsl:variable name="pos" select="position()" /> 
    <boundle> 
     <xsl:copy-of select="$allProjects[ 
     position() &gt;= $pos and position() &lt; ($pos + $perGroup) 
     ]" /> 
    </boundle> 
    </xsl:template> 
</xsl:template> 
+0

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

+1

Это невозможно сделать намного проще. Вы можете сделать «» в обмен, но с точки зрения обработки это почти то же самое , Также, как я это сделал, шаблон '' является автономным. Что касается потенциального использования ключа XSL: поскольку нет последовательного диапазона проектов, 'position() mod x' не даст желаемых результатов. Кроме того, описанное выше параметризуется, XSL-ключ должен быть жестко закодирован. – Tomalak

+0

является правильным. При работе с моим решением (теперь он удален) он становится безнадежно сложным, имея дело с различными случаями краев, когда второй или третий проект в пакете перемещается в следующий или следующий плюс один клиентский узел. – Richard

0

Я могу рекомендовать следующую ссылку http://www.jenitennison.com/xslt/grouping/, который помог мне выяснить, как группа различного количества элементов в некоторые категории на основе содержимого в документе XML.

+1

Вы не должны просто указывать ссылку на другой сайт в качестве ответа, так как сайт может устареть в будущем. Вместо этого нажмите ссылку «изменить» в этом ответе и включите в нее основные части решения с этой страницы. См .: http://meta.stackexchange.com/q/8259 –

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