xsl-list
[Top] [All Lists]

Re: [xsl] flat list of contents and for-each-group

2009-08-23 09:09:18
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>
--~--

<Prev in Thread] Current Thread [Next in Thread>