[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: flat list of contents and for-each-group
Stanislav PejE!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">. 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/
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|