Stanislav Pejša wrote:
However, I posted an ideal scenario and forgot to mention that "Section"
does not have to be in the source XML and "Part" is then a direct child
of "Chapter", see coding for Chapter III. I have also simplified the
mark-up for the desired output and used element with name of the
component rather than placing the name of the component into attribute
which is more realistic, e.g. <level01 type="chapter">.
I tried to modify your template accordingly, but I failed. I really
appreciate you sent me the template it helped me a lot, but it also made
me realize that I did not take into consideration some variations in the
source XML. Can your template be adjusted in order to addressed this new
situation?
Here is an adjusted stylesheet:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/2009/mf"
exclude-result-prefixes="xs mf"
version="2.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:function name="mf:group" as="element()*">
<xsl:param name="parts" as="element()*"/>
<xsl:param name="patterns" as="xs:string*"/>
<xsl:param name="names" as="xs:string*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="$parts"
group-starting-with="b_part[matches(level_name, $patterns[1])]">
<xsl:element name="level{format-number($level, '00')}">
<xsl:attribute name="type" select="$names[1]"/>
<title><xsl:value-of select="level_name"/></title>
<xsl:choose>
<xsl:when test="$patterns[2] and (current-group() except
.)[matches(level_name, $patterns[2])]">
<xsl:sequence select="mf:group(current-group() except .,
$patterns[position() gt 1], $names[position() gt 1], $level + 1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group() except .">
<xsl:with-param name="level" select="$level + 1"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:for-each-group>
</xsl:function>
<xsl:template match="book">
<xsl:copy>
<xsl:copy-of select="title"/>
<toc>
<p>Table of contents</p>
<xsl:sequence select="mf:group(b_part, ('^Chapter',
'^(Section|[A-Z]\))'), ('chapter', 'section'), 1)"/>
</toc>
</xsl:copy>
</xsl:template>
<xsl:template match="b_part">
<xsl:param name="level" as="xs:integer"/>
<xsl:element name="level{format-number($level, '00')}">
<xsl:attribute name="type" select="'part'"/>
<title><xsl:value-of select="level_name"/></title>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
The output with Saxon 9.2, when run against your last input, is as follows:
<book>
<title>Some Title</title>
<toc>
<p>Table of contents</p>
<level01 type="chapter">
<title>Chapter I: Title of Chapter I</title>
<level02 type="section">
<title>Section 1: Title of section 1</title>
<level03 type="part">
<title>Part 1: Title of Part 1</title>
</level03>
<level03 type="part">
<title>Part 2: Title of Part 2</title>
</level03>
<level03 type="part">
<title>Part n: Title of Part n </title>
</level03>
</level02>
</level01>
<level01 type="chapter">
<title>Chapter II: Title of Chapter II</title>
<level02 type="section">
<title>A) Title of Section A</title>
<level03 type="part">
<title>A/1 Title of Part 1</title>
</level03>
<level03 type="part">
<title>A/n Title of Part n</title>
</level03>
</level02>
<level02 type="section">
<title>B) Title of Section A</title>
<level03 type="part">
<title>B/1 Title of Part 1</title>
</level03>
<level03 type="part">
<title>B/n Title of Part n</title>
</level03>
</level02>
</level01>
<level01 type="chapter">
<title>Chapter III: Title of Chapter III</title>
<level02 type="part">
<title>III/1 Title of Part 1</title>
</level02>
<level02 type="part">
<title>III/2 Title of Part n</title>
</level02>
</level01>
</toc>
</book>
--
Martin Honnen
http://msmvps.com/blogs/martin_honnen/
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--