Dynamic output elements in XSLT

Sometimes the output element that has to be emitted by an XSLT transformation is not known in advance. For example, using the book structure from one of the previous posts
<book title="Sample book">
  <chapter title="First chapter">
    <section title="Section in first chapter">
      <section title="Chunk of text within a section">
        <para>My paragraph</para>
      </section>
    </section>
  </chapter>
</book>
… we'd like to generate HTML H1 heading for the chapter and H2Hx headings for the sections. It's obvious that the heading element's name can be computed easily as 'H'+number-of-ancestors. The corresponding XSLT template is of course a bit more complex and uses the xsl:element tag to generate the output element.
<xsl:template match="chapter|section">
  <xsl:element name="{concat('h',count(ancestor::*))}">
    <xsl:value-of select="@title" />
  </xsl:element>
  <xsl:apply-templates />
</xsl:template>

The xsl:element expects a QName (a string specifying the element's name) as its name attribute. To insert dynamically computed element's name, you have to use curly braces around the expression.

No comments:

Post a Comment