two-level grouping problem

Here should go questions about transforming XML with XSLT and FOP.
IowaBoy
Posts: 2
Joined: Thu Mar 06, 2008 5:10 pm

two-level grouping problem

Post by IowaBoy »

I have the following xml input (much paragraph data has been removed to reveal heading structure I am attempting to group.

<book>
<bodymatter>
<chapter>Fun and Games</chapter>
<a_head>Definitions</a_head>
<pagenum page="normal" id="page_1">1</pagenum>
<a_head>Completing the Sentence</a_head>
<pagenum page="normal" id="page_2">2</pagenum>
<!--more like this-->
<chapter>Let’s Eat!</chapter>
<a_head>Definitions</a_head>
<pagenum page="normal" id="page_7">7</pagenum>
<a_head>Completing the Sentence</a_head>
<!--etc-->
<chapter>Terms of Change</chapter>
<!--much more like this-->
</bodymatter>
</book>


I am attempting to add the following structure to the document:

<book>
<bodymatter>
<level1 class="chapter">
<chapter>Fun and Games</chapter>
<level2>
<a_head>Definitions</a_head>
<pagenum page="normal" id="page_1">1</pagenum>
</level2>
<level2>
<a_head>Completing the Sentence</a_head>
<pagenum page="normal" id="page_2">2</pagenum>
</level2>
<!--more like this-->
</level1>
<level1 class="chapter">
<chapter>Let’s Eat!</chapter>
<level2>
<a_head>Definitions</a_head>
<pagenum page="normal" id="page_7">7</pagenum>
</level2>
<level2>
<a_head>Completing the Sentence</a_head>
<pagenum page="normal" id="page_7">7</pagenum>
</level2>
<!--etc-->
</level1>
<level1 class="chapter">
<chapter>Terms of Change</chapter>
<!--much more like this-->
</level1>
</bodymatter>
</book>

Here is my current stylesheet:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="bodymatter">
<bodymatter>
<xsl:for-each-group select="*" group-starting-with="chapter">
<level1 class="chapter">
<xsl:apply-templates select="current-group()"/>
</level1>
<xsl:for-each-group select="current-group()" group-starting-with="a_head">
<level2>
<xsl:copy-of select="current-group()"/>
</level2>
</xsl:for-each-group>
</xsl:for-each-group>
</bodymatter>
</xsl:template>
</xsl:stylesheet>

As you can see, I am using xslt 2.0. This sheet produces output in which the first chapter is skipped by the <level2> grouping sequence. Then the <level2> cuts in surrounding the <chapter> as well as the <a_head> elements. I copied enough of the output so that you can see that the <level2> sequence seems to skip over every other <chapter>. Any suggestions?


<book>
<bodymatter>
<level1 class="chapter">
<chapter>Fun and Games</chapter>
<a_head>Definitions</a_head>
<pagenum page="normal" id="page_1">1</pagenum>
<a_head>Completing the Sentence</a_head>
<pagenum page="normal" id="page_2">2</pagenum>
<a_head>Analogies </a_head>
<pagenum page="normal" id="page_3">3</pagenum>
<a_head>Writing Prompt: Sports Party</a_head>
<pagenum page="normal" id="page_4">4</pagenum>
<a_head>Vocabulary Review</a_head>
<pagenum page="normal" id="page_5">5</pagenum>
<a_head>Vocabulary Review</a_head>
<pagenum page="normal" id="page_6">6</pagenum>
</level1>
<level2>
<chapter>Fun and Games</chapter>
</level2>
<level2>
<a_head>Definitions</a_head>
<pagenum page="normal" id="page_1">1</pagenum>
</level2>
<level2>
<a_head>Completing the Sentence</a_head>
<pagenum page="normal" id="page_2">2</pagenum>
</level2>
<level2>
<a_head>Analogies </a_head>
<pagenum page="normal" id="page_3">3</pagenum>
</level2>
<level2>
<a_head>Writing Prompt: Sports Party</a_head>
<pagenum page="normal" id="page_4">4</pagenum>
</level2>
<level2>
<a_head>Vocabulary Review</a_head>
<pagenum page="normal" id="page_5">5</pagenum>
</level2>
<level2>
<a_head>Vocabulary Review</a_head>
<pagenum page="normal" id="page_6">6</pagenum>
</level2>
<level1 class="chapter">
<chapter>Let’s Eat!</chapter>
<a_head>Definitions</a_head>
<pagenum page="normal" id="page_7">7</pagenum>
<a_head>Completing the Sentence</a_head>
<pagenum page="normal" id="page_8">8</pagenum>
<!--etc-->
</bodymatter>
</book>
IowaBoy
Posts: 2
Joined: Thu Mar 06, 2008 5:10 pm

Re: two-level grouping problem

Post by IowaBoy »

I have found a solution to my grouping problem:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>

<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="bodymatter">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each-group
select="*"
group-starting-with="chapter">
<level1 class="chapter" id="{position()}">
<xsl:for-each-group
select="current-group()"
group-starting-with="a_head">
<xsl:choose>
<xsl:when test="current-group()[1][self::a_head]">
<level2>
<xsl:apply-templates select="current-group()"/>
</level2>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</level1>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Post Reply