Search

I want to create three unordered lists with three items in each. The XML data structure is the same for all lists, they are pulled from the same section but with different kind of filters.

I was just about to create three different utilities, where just the template-match would differ between them. But I guess there is a way that I can use the same template for all three list?

Something like this — it will match three data source names:

<xsl:template match="data">
    <xsl:apply-templates select="datasource-1" mode="build-list"/>
</xsl:template>

<xsl:template match="datsaource-1 | datasource-2 | datasource-3" mode="build-list">
    <ul>
        <xsl:apply-templates select="item" mode="build-list-item"/>
    </ul>
</xsl:template>

<xsl:template match="item" mode="build-list-item">
    <li>
        <xsl:value-of select="text()"/>
    </li>
</xsl:template>

Thanks. If I understand the code right, the mode attribute is needed to allow the templates to be matched more than once?

No, not necessarily. The above will work without the modes, but adding a mode is like adding scope or a namespace — it means that if you had another apply-templates on the same node elsewhere in your code it won’t run this template as well.

The final template matching on item deserves a mode since you may well be matching on item nodes elsewhere in your page — you only want this template to run in this instance — so it will only run when the matching mode is passed.

Okey. So with mode, you can reuse the same DS in many places on the same page?

Sort of. Really it’s the apply-templates that allows you to process a datasource more than once, since you can apply templates to any part of your source xml (your data sources). The mode just lets you specify what templates you want to apply, if you apply templates to the same part of your source xml more than once.

A good example would be if you had a DS with articles, and you wanted to output both a table of contents including just a title, as well as the full content of each article. You would apply-templates to your articles DS, but you might have a ‘toc’ mode and a ‘full’ mode.

However, be aware of that when using modes and some sort of “catch all” template, eg. for debugging:

<xsl:template match="*">
    <xsl:text>Unhandled element: </xsl:text>
    <xsl:value-of select="name()"/>
</xsl:template>

The “catch all” template won’t match against your apply-templates using modes (when no other matching template is found). This could cause your content to just drop without being processed.

In XSLT2.0 you could always solve this by defining mode="#all" in the “catch all”-template but this isn’t possible in XSLT1.0.

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details