Search code examples
xslt-2.0xslt-grouping

XSLT current-groups() issue


I've been having a bit of trouble with an HTML file that I'm trying to translate. Basically, the relevant part of the source structure as it currently stands is this:

<h2 />
<h3 />
<table />
<table />
<h3 />
<table />
<table />
<h3 />
<table />
<h3 />
<h3 />
<table />
<table />
<h2 />
<h3 />
...

and so on. Each of the contents of these are being translated in different ways, but the problem I'm currently having is in grouping them correctly. Essentially, I want it to end up like the following:

<category>
    <h2 />
    <container>
        <h3 />
        <table />
        <table />
    </container>
    <container>
        <h3 />
        <table />
        <table />
    </container>
    <container>
        <h3 />
        <table />
    </container>
    <container>
        <h3 />
    </container>
    <container>    
        <h3 />
        <table />
        <table />
    </container>
</category>
<category>
    <h2 />
    <container>
        <h3 />
        ...

to achieve this, I've been using the following code:

<xsl:for-each-group select="node()"group-starting-with="xh:h2">
    <category>
        <xsl:apply-templates select="xh:h2"/>
        <xsl:for-each-group select="current-group()" 
                    group-starting-with="xh:h3">
            <container>
                <xsl:apply-templates select="current-group()[node()]"/>
            </container>
        </xsl:for-each-group>
    </category>
</xsl:for-each-group>

However, the output I get from this is as follows:

<category>
    <h2 />
    <container>
        <h3 />
        <table />
        <table />
        <h3 />
        <table />
        <table />
        <h3 />
        <table />
        <h3 />   
        <h3 />
        <table />
        <table />
    </container>
</category>
<category>
    <h2 />
    <container>
        <h3 />
        ...

The first for-loop function is working as expected, however the second does not appear to be. If I use <xsl:copy-of> to output the first element in the <current-group> in the second for-loop, it shows the <h2> element, where that element should not even be in the group.

If anyone can point out where I'm going wrong, or offer a better solution, it would be greatly appreciated.


Solution

  • I think you want to change

    <xsl:for-each-group select="node()" group-starting-with="xh:h2">
        <category>
            <xsl:apply-templates select="xh:h2"/>
            <xsl:for-each-group select="current-group()" 
                        group-starting-with="xh:h3">
    

    to

    <xsl:for-each-group select="*" group-starting-with="xh:h2">
        <category>
            <xsl:apply-templates select="."/>
            <xsl:for-each-group select="current-group() except ." 
                        group-starting-with="xh:h3">
    

    That way the inner for-each-group processes the h3 and table elements but no the h2 element starting the outer group.

    If you need more help then consider to post small but complete samples with namespaces present allowing us to reproduce the problem with the undesired output.