Этот вопрос необходимо отредактировать, чтобы каждый мог понять, в чем на самом деле проблема . Комментарий Томалака показывает, что ОП " хочет списки элементов в алфавитно упорядоченной сетке. Один список для каждой буквы. Четыре буквы по горизонтали, столько же, сколько требуется по вертикали "
Следующее преобразование :
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
extension-element-prefixes="ext"
>
<xsl:variable name="vDoc" select="/"/>
<xsl:variable name="vNumCols" select="4"/>
<xsl:variable name="vLower"
select="'abcdefghijklmnopqrstuvwxyz'"
/>
<xsl:variable name="vUpper"
select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"
/>
<xsl:key name="rows-by-FirstLetter" match="Row"
use="translate(substring(@Title,1,1),
'abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" />
<xsl:variable name="vrtfStartLetters">
<xsl:for-each select=
"/*/*/Row
[count(.
|
key('rows-by-FirstLetter',
translate(substring(@Title,1,1),
$vLower,
$vUpper)
)[1]
)
= 1
]">
<startLetter>
<xsl:value-of select=
"translate(substring(@Title,1,1),
$vLower,
$vUpper)"/>
</startLetter>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="vStartLetters" select=
"ext:node-set($vrtfStartLetters)"/>
<xsl:template match="Rows">
<table>
<xsl:apply-templates select=
"$vStartLetters/*[position() mod $vNumCols = 1]">
<xsl:with-param name="pDoc" select="$vDoc"/>
<xsl:with-param name="pNumCols" select="$vNumCols"/>
</xsl:apply-templates>
</table>
</xsl:template>
<xsl:template match="startLetter">
<xsl:param name="pDoc"/>
<xsl:param name="pNumCols" select="10"/>
<tr>
<xsl:apply-templates mode="copy" select=
". | following-sibling::*
[not(position() >= $pNumCols)]">
<xsl:with-param name="pDoc" select="$pDoc"/>
<xsl:sort/>
</xsl:apply-templates>
</tr>
</xsl:template>
<xsl:template match="startLetter" mode="copy">
<xsl:param name="pDoc"/>
<xsl:variable name="pThis" select="."/>
<td>
<xsl:value-of select="."/>
<br />
<table>
<xsl:for-each select="$pDoc">
<xsl:for-each select="key('rows-by-FirstLetter', $pThis)">
<tr><td><xsl:value-of select="@Title"/></td></tr>
</xsl:for-each>
</xsl:for-each>
</table>
</td>
</xsl:template>
</xsl:stylesheet>
при применении к этому документу XML :
<dsQueryResponse>
<Rows>
<Row Title="Agenda" />
<Row Title="Accrual" />
<Row Title="Ads" />
<Row Title="Averages" />
<Row Title="Bindings" />
<Row Title="Budget" />
<Row Title="Cars" />
<Row Title="Categories" />
<Row Title="Costs" />
<Row Title="Policy" />
<Row Title="Politics" />
<Row Title="Reevaluations" />
<Row Title="Report" />
</Rows>
</dsQueryResponse>
дает желаемый результат :
<table>
<tr>
<td>A
<br/>
<table>
<tr>
<td>Agenda</td>
</tr>
<tr>
<td>Accrual</td>
</tr>
<tr>
<td>Ads</td>
</tr>
<tr>
<td>Averages</td>
</tr>
</table>
</td>
<td>B
<br/>
<table>
<tr>
<td>Bindings</td>
</tr>
<tr>
<td>Budget</td>
</tr>
</table>
</td>
<td>C
<br/>
<table>
<tr>
<td>Cars</td>
</tr>
<tr>
<td>Categories</td>
</tr>
<tr>
<td>Costs</td>
</tr>
</table>
</td>
<td>P
<br/>
<table>
<tr>
<td>Policy</td>
</tr>
<tr>
<td>Politics</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>R
<br/>
<table>
<tr>
<td>Reevaluations</td>
</tr>
<tr>
<td>Report</td>
</tr>
</table>
</td>
</tr>
</table>
Обратите внимание на три вещи :
Мы используем функцию расширения ( exslt ) ext: node-set () для преобразования промежуточного результат из RTF (Result-Fragment) во временное дерево.
<xsl:for-each select="$pDoc">
, необходимый для того, чтобы исходный XML-документ снова стал текущим XML-документом, чтобы функция key () использовала индекс, созданный для этого документа, а не для временного дерева.
Каждая начальная буква, которая должна начинать новую строку (4) начальных букв, обрабатывается в специальном шаблоне, в котором создается <tr>
. Затем эта и остальные (3) начальные буквы в строке обрабатываются в теле <tr>
в режиме «копирования», просто создавая <td>
каждая.
Здесь мы рассмотрели и продемонстрировали несколько передовых методов XSLT :
- Использование оператора
mod
для группировки по количеству.
- Использование функции () для документа, отличного от текущего.
- Режимы
- Преобразование RTF во временное дерево
Наслаждайтесь :)