Есть ряд проблем с вашим текущим XSLT
- Ваш шаблон соответствует узлу документа, который в вашем случае является родителем элемента
table
, а не самого элемента table
,Поскольку вы пытаетесь сгруппировать дочерние элементы tbody
, ваш шаблон должен соответствовать элементу table
xsl:value-of
, который возвращает только текстовое значение узла.Вы должны использовать xsl:copy-of
здесь (или xsl:apply-templates
в сочетании с шаблоном идентификации).Вы также должны выбрать все элементы в группе, а не только текущий элемент. - Вы не учли, что происходит с узлами в таблице, отличными от
tbody
Итак,ваш XSLT должен выглядеть следующим образом ....
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="table">
<table>
<xsl:for-each-group select="*" group-adjacent="boolean(self::tbody)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<tbody>
<xsl:apply-templates select="current-group()/*"/>
</tbody>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</table>
</xsl:template>
</xsl:stylesheet>
Обратите внимание, что если вы используете XSLT 3.0, вы можете заменить шаблон идентификации следующим образом:
<xsl:mode on-no-match="shallow-copy"/>
С другой стороны, если вы на самом деле используете только XSLT 1.0, то вам нужно сделать Muenchian Grouping .Это означает определение ключа следующим образом:
<xsl:key name="table" match="table/*" use="boolean(self::tbody)" />
Затем, вместо использования xsl:for-each-group
, сделайте это (хотя это сгруппирует все элементы tbody
, а не только смежные)
<xsl:for-each select="*[generate-id() = generate-id(key('table', boolean(self::tbody))[1])]">
Вместо этого попробуйте этот XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="table" match="table/*" use="boolean(self::tbody)" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="table">
<table>
<xsl:for-each select="*[generate-id() = generate-id(key('table', boolean(self::tbody))[1])]">
<xsl:choose>
<xsl:when test="self::tbody">
<tbody>
<xsl:apply-templates select="key('table', true())/*"/>
</tbody>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="key('table', false())" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
Конечно, после всего этого, ответ Michael.Hor257k гораздо проще в этом случае.(Хотя, безусловно, стоит ознакомиться с Muenchian Grouping, если вы действительно застряли с XSLT 1.0).