With the following XML
<page>
<chunk id="1001" sequence="1">
<meta>Inline</meta>
<body>Inline chunk 1</body>
</chunk>
<chunk id="1002" sequence="2">
<meta>Tabs</meta>
<body>Tab chunk 1</body>
</chunk>
<chunk id="1054" sequence="3">
<meta>Tabs</meta>
<body>Tab chunk 2</body>
</chunk>
<chunk id="1023" sequence="4">
<meta>Inline</meta>
<body>Inline chunk 2</body>
</chunk>
<chunk id="1013" sequence="5">
<meta>Tabs</meta>
<body>Tab chunk 3</body>
</chunk>
<chunk id="1072" sequence="6">
<meta>Tabs</meta>
<body>Tab chunk 4</body>
</chunk>
</page>
I would like to apply an XSL template to output this:
<main>
<section class="Inline>
<div>Inline chunk 1</div>
</section>
<section class="Tabs>
<div>Tab chunk 1</div>
<div>Tab chunk 2</div>
</section>
<section class="Inline>
<div>Inline chunk 2</div>
</section>
<section class="Tabs>
<div>Tab chunk 3</div>
<div>Tab chunk 4</div>
</section>
</main>
Basically I would like to output the chunk
in the order of their ./@sequence
, but group them based on their ./meta
value when possible. By "possible", I mean only group them if they have the same ./meta
value and next to each other in sequence.
Using Muenchian Method, I could group the chunk
by ./meta
, but only get the following result:
<main>
<section class="Inline>
<div>Inline chunk 1</div>
<div>Inline chunk 2</div>
</section>
<section class="Tabs>
<div>Tab chunk 1</div>
<div>Tab chunk 2</div>
<div>Tab chunk 3</div>
<div>Tab chunk 4</div>
</section>
</main>
This is the XSLT I use:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kBucketByLabel" match="/page/chunk" use="./meta" />
<!-- Then we override/define a template to match "/SAM" and write our body HTML here. -->
<xsl:template match="/page" mode="body">
<main>
<xsl:apply-templates select="chunk[generate-id() = generate-id( key('kBucketByLabel', ./meta)[1] )]" mode="bucket">
<xsl:sort select="@sequence" data-type="number" />
</xsl:apply-templates>
</main>
</xsl:template>
<xsl:template match="chunk" mode="bucket">
<xsl:variable name="bucket" select="./meta" />
<section class="{$bucket}">
<xsl:for-each select="key('kBucketByLabel', $bucket)">
<div><xsl:value-of select="./body"/></div>
</xsl:for-each>
</section>
</xsl:template>
</xsl:stylesheet>