Я новичок в XSLT. Я знаю, что мне нужно использовать xsl: for-each-group, но я не могу понять ничего, кроме основного списка. Будет ли какая-то рекурсия работать лучше? Подойдет любое решение XSLT 1.0 или 2.0.
Ниже приведен пример XML. Обратите внимание, что наиболее важным атрибутом для организации данных в древовидную структуру является @taxonomy. Другие атрибуты @taxonomyName и @level предоставляются в качестве необязательных вспомогательных атрибутов.
<?xml version="1.0" encoding="utf-8"?>
<documents>
<document level="0" title="Root document test" taxonomy="" taxonomyName="" />
<document level="1" title="Level one document test" taxonomy="\CategoryI" taxonomyName="CategoryI" />
<document level="1" title="Level one document test #2" taxonomy="\CategoryII" taxonomyName="CategoryII" />
<document level="2" title="Level two document test" taxonomy="\CategoryII\SubcategoryA" taxonomyName="SubcategoryA" />
<document level="2" title="Level two document test #2" taxonomy="\CategoryII\SubcategoryA" taxonomyName="SubcategoryA" />
<document level="3" title="Level three document test" taxonomy="\CategoryII\SubcategoryA\Microcategory1" taxonomyName="Microcategory1" />
<document level="2" title="Level two, no level one test" taxonomy="\CategoryIII\SubcategoryZ" taxonomyName="SubcategoryZ" />
</documents>
Вот ожидаемый результат. (Обратите внимание, что в выводе нет необходимости делать отступы. Я сделал это здесь для удобства чтения.)
<ul>
<li>Root document test</li>
<li>CategoryI
<ul>
<li>Level one document test</li>
</ul>
</li>
<li>CategoryII
<ul>
<li>Level one document test #2</li>
<li>SubcategoryA
<ul>
<li>Level two document test</li>
<li>Level two document test #2</li>
<li>Microcategory1
<ul>
<li>Level three document test</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>CategoryIII
<ul>
<li>SubcategoryZ
<ul>
<li>Level two, no subcategory test</li>
</ul>
</li>
</ul>
</li>
</ul>
Вот лучшее, что я могу сделать.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:key name="contacts-by-taxonomy" match="document" use="@taxonomy" />
<xsl:template match="documents">
<ul>
<xsl:for-each-group select="document" group-by="@taxonomy">
<xsl:sort select="@taxonomy" />
<li>
<h3><xsl:value-of select="current-grouping-key()"/></h3>
<ul>
<xsl:for-each select="current-group()">
<li><xsl:value-of select="@title"/></li>
</xsl:for-each>
</ul>
</li>
</xsl:for-each-group>
</ul>
</xsl:template>
</xsl:stylesheet>
Я буду продолжать пыхтеть, но буду вечно благодарен, если кто-нибудь сможет бросить мне спасательный жилет. Спасибо!