Группировка xsl по элементу xml для повторяющихся узлов в xslt1 в вывод html-таблицы
У меня есть сложная структура XML, которая выглядит следующим образом:
<Items>
<Item>
<ItemTexts>
<ItemText>
<ItemTextsType>type1</ItemTextsType>
<ItemTextsTypeDesc>description11</ItemTextsTypeDesc>
<ItemTextsLine>1</ItemTextsLine>
</ItemText>
<ItemText>
<ItemTextsType>type1</ItemTextsType>
<ItemTextsTypeDesc>description12</ItemTextsTypeDesc>
<ItemTextsLine>2</ItemTextsLine>
</ItemText>
<ItemText>
<ItemTextsType>type2</ItemTextsType>
<ItemTextsTypeDesc>description21</ItemTextsTypeDesc>
<ItemTextsLine>3</ItemTextsLine>
</ItemText>
<ItemText>
<ItemTextsType>type2</ItemTextsType>
<ItemTextsTypeDesc>description22</ItemTextsTypeDesc>
<ItemTextsLine>4</ItemTextsLine>
</ItemText>
</ItemTexts>
</Item>
<Item>
<ItemTexts>
<ItemText>
<ItemTextsType>type1</ItemTextsType>
<ItemTextsTypeDesc>description11</ItemTextsTypeDesc>
<ItemTextsLine>1</ItemTextsLine>
</ItemText>
<ItemText>
<ItemTextsType>type1</ItemTextsType>
<ItemTextsTypeDesc>description12</ItemTextsTypeDesc>
<ItemTextsLine>2</ItemTextsLine>
</ItemText>
<ItemText>
<ItemTextsType>type2</ItemTextsType>
<ItemTextsTypeDesc>description21</ItemTextsTypeDesc>
<ItemTextsLine>3</ItemTextsLine>
</ItemText>
<ItemText>
<ItemTextsType>type2</ItemTextsType>
<ItemTextsTypeDesc>description22</ItemTextsTypeDesc>
<ItemTextsLine>4</ItemTextsLine>
</ItemText>
</ItemTexts>
</Item>
<Item>
<ItemTexts>
<ItemText>
<ItemTextsType>type1</ItemTextsType>
<ItemTextsTypeDesc>description11</ItemTextsTypeDesc>
<ItemTextsLine>1</ItemTextsLine>
</ItemText>
<ItemText>
<ItemTextsType>type1</ItemTextsType>
<ItemTextsTypeDesc>description12</ItemTextsTypeDesc>
<ItemTextsLine>2</ItemTextsLine>
</ItemText>
<ItemText>
<ItemTextsType>type2</ItemTextsType>
<ItemTextsTypeDesc>description21</ItemTextsTypeDesc>
<ItemTextsLine>3</ItemTextsLine>
</ItemText>
<ItemText>
<ItemTextsType>type2</ItemTextsType>
<ItemTextsTypeDesc>description22</ItemTextsTypeDesc>
<ItemTextsLine>4</ItemTextsLine>
</ItemText>
</ItemTexts>
</Item>
<Item>
<ItemTexts>
<ItemText>
<ItemTextsType>type3</ItemTextsType>
<ItemTextsTypeDesc>description31</ItemTextsTypeDesc>
<ItemTextsLine>1</ItemTextsLine>
</ItemText>
<ItemText>
<ItemTextsType>type3</ItemTextsType>
<ItemTextsTypeDesc>description32</ItemTextsTypeDesc>
<ItemTextsLine>2</ItemTextsLine>
</ItemText>
<ItemText>
<ItemTextsType>type2</ItemTextsType>
<ItemTextsTypeDesc>description21</ItemTextsTypeDesc>
<ItemTextsLine>3</ItemTextsLine>
</ItemText>
<ItemText>
<ItemTextsType>type2</ItemTextsType>
<ItemTextsTypeDesc>description22</ItemTextsTypeDesc>
<ItemTextsLine>4</ItemTextsLine>
</ItemText>
</ItemTexts>
</Item>
</Items>
каждый <Item>
имеет МНОГИЕ больше элементов XML, но я не буду сейчас их указывать.
Я использую xsl для каждого элемента, например:
<xsl:for-each select="Items/Item">
и я создаю таблицу со строками для каждого <Item>
и много <td>
в каждом ряду.
Мне нужен пример того, как группировать <ItemText>
от <ItemTextsType>
индивидуально для каждого <Item>
,
Я организую результаты в таблице как:
<table>
<%--tr for each Item in Items--%>
<tr>
<td>
some value from xml element according <b> Item1 </b>
</td>
<td>
some more value from xml element according <b> Item1 </b>
</td>
<%--
.
.
.
--%>
<td>
<table width="100%" dir="ltr">
<tbody>
<tr style="background-color: #507CD1; text-align: center">
<td colspan="3" style="font: bold; color: white">
Item1
</td>
</tr>
<tr>
<td style="height: 35px; font: bold; color: #507CD1;">
type1
</td>
</tr>
<tr>
<td>
description11
</td>
</tr>
<tr>
<td>
description12
</td>
</tr>
<tr>
<td style="height: 35px; font: bold; color: #507CD1;">
type2
</td>
</tr>
<tr>
<td>
description21
</td>
</tr>
<tr>
<td>
description22
</td>
</tr>
</tbody>
</table>
</td>
<td>
even more value from xml element according <b> Item1 </b>
</td>
<%--
.
.
.
--%>
</tr>
<tr>
<td>
some value from xml element according <b> Item2 </b>
</td>
<td>
some more value from xml element according <b> Item2 </b>
</td>
<%--
.
.
.
--%>
<td>
<table width="100%" dir="ltr">
<tbody>
<tr style="background-color: #507CD1; text-align: center">
<td colspan="3" style="font: bold; color: white">
Item2
</td>
</tr>
<tr>
<td style="height: 35px; font: bold; color: #507CD1;">
type1
</td>
</tr>
<tr>
<td>
description11
</td>
</tr>
<tr>
<td>
description12
</td>
</tr>
<tr>
<td style="height: 35px; font: bold; color: #507CD1;">
type2
</td>
</tr>
<tr>
<td>
description21
</td>
</tr>
<tr>
<td>
description22
</td>
</tr>
</tbody>
</table>
</td>
<td>
even more value from according <b> Item2 </b>
</td>
<%--
.
.
.
--%>
</tr>
<%-- and so on--%>
</table>
Дело в том, что существует отдельная группировка для каждого <Item>
в свое собственное <tr><td><table>
и внутри этого <table>
там глотает <ItemTextsType>
Я пробовал что-то вроде
<xsl:key name="item-texts-type" match="ItemText" use="ItemTextsType" />
<xsl:for-each select="ItemTexts/ItemText[count(. | key('item-texts-type', ItemTextsType)[1]) = 1]">
<xsl:sort select="ItemTextsType" />
<tr>
<td style ="height:35px;font: bold; color:#507CD1;">
<xsl:value-of select="ItemTextsType" />
</td>
</tr>
<xsl:for-each select="key('item-texts-type', ItemTextsType)">
<tr>
<td>
<xsl:value-of select="ItemTextsTypeDesc" />
</td>
</tr>
</xsl:for-each>
</xsl:for-each>
но он работает только на неповторяющихся узлах (если был только один <Item>
это будет работать нормально). Я не могу изменить XML, потому что это исходит от клиента.
Пожалуйста, помогите мне, мне это нужно как можно скорее.
Спасибо!!!!
1 ответ
Если вы хотите отдельную группу для каждого Item
тогда одним из способов достижения этого было бы включение некоторого уникального идентификатора для содержащего Item
как часть значения ключа, например
<xsl:key name="item-texts-type" match="ItemText"
use="concat(generate-id(ancestor::Item), '|', ItemTextsType)" />
<!-- assuming the context node is the current Item -->
<xsl:variable name="currentItemId" select="generate-id()" />
<xsl:for-each select="ItemTexts/ItemText[count(. | key('item-texts-type',
concat($currentItemId, '|', ItemTextsType))[1]) = 1]">
<!-- .... -->
<xsl:for-each select="key('item-texts-type',
concat($currentItemId, '|', ItemTextsType))">
Это было бы гораздо проще, если бы вы могли использовать XSLT 2.0, конечно...