Кажется, по большей части вы просто хотите сгладить вложенную иерархию, поэтому используйте для этого рекурсию. Кроме того, чтобы объединить / сгруппировать самый глубокий уровень, используйте группирование, например, в XSLT 1, с группировкой по Мюнхену и ключом:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" indent="yes" version="5" doctype-system="about:legacy-doctype"/>
<xsl:key name="table-group"
match="*[* and not(*/*)]"
use="concat(generate-id(..), '|', local-name())"/>
<xsl:template match="*[*]">
<table>
<thead>
<tr>
<xsl:apply-templates select="*[not(*)]" mode="header"/>
</tr>
</thead>
<tbody>
<tr>
<xsl:apply-templates select="*[not(*)]"/>
</tr>
</tbody>
</table>
<xsl:apply-templates select="*[*/*]"/>
<xsl:apply-templates
select="*[* and not(*/*)][generate-id() = generate-id(key('table-group', concat(generate-id(..), '|', local-name()))[1])]" mode="merge-groups"/>
</xsl:template>
<xsl:template match="*[not(*)]" mode="header">
<th>
<xsl:value-of select="local-name()"/>
</th>
</xsl:template>
<xsl:template match="*[not(*)]">
<td>
<xsl:value-of select="."/>
</td>
</xsl:template>
<xsl:template match="*[*]" mode="merge-groups">
<table>
<thead>
<tr>
<xsl:apply-templates select="*[not(*)]" mode="header"/>
</tr>
</thead>
<tbody>
<xsl:apply-templates select="key('table-group', concat(generate-id(..), '|', local-name()))" mode="row"/>
</tbody>
</table>
</xsl:template>
<xsl:template match="*" mode="row">
<tr>
<xsl:apply-templates select="*"/>
</tr>
</xsl:template>
<xsl:template match="/">
<html>
<head>
<title>.NET XSLT Fiddle Example</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/ncnu9AZ/1
Если Вы новичок в мюнхенской группировке в XSLT 1, пожалуйста, используйте любой учебник или онлайн-введение по мюнхенской группировке в XSLT 1, чтобы познакомить вас с этим подходом, один онлайн-источник - http://www.jenitennison.com/xslt/grouping/muenchian.html.
В приведенной выше таблице стилей, поскольку необходимо сгруппировать элементы, не вложенные далее только в контексте родительского контейнера, используемый ключ включает в себя сгенерированный идентификатор родительского элемента (generate-id(...)
). Поэтому вызов key('table-group', concat(generate-id(..), '|', local-name()))
в контексте элемента дает нам набор узлов с группой элементов с одинаковым именем внутри одного и того же родителя. И с целым предикатом [generate-id() = generate-id(key('table-group', concat(generate-id(..), '|', local-name()))[1])]
мы просто устанавливаем sh, что первый элемент в порядке документов в этом наборе узлов в настоящее время обрабатывается. generate-id() = generate-id(key(...)[1])
- это в основном способ XSLT 1 для выражения того, что можно сделать в XSLT 2 или более поздней версии, как . is key(...)[1]
, то есть для проверки идентичности узла элемента контекста в предикате и первого узла, возвращенного этим key(...)
звоните.