Sorting a bibliography

It is possible to present a sorted bibliography, even if the biblioentry elements are not in sorted order in the source document. One of the great things about XSLT is that it can rearrange the content before it formats it. You have to customize the template that handles the bibliodiv to add an xsl:sort instruction. You could also customize the bibliography element in the same way, but that is a much longer template so it will not be shown here. It might just be easier to put a bibliodiv inside your bibliography.

The trick to sorting the bibliography is to not process the biblioentry elements in document order, but in the order you specify. The original template for bibliodiv has an empty xsl:apply-templates instruction, which processes the entries in document order. So you will want to insert an xsl:sort instruction inside it. The following example sorts on the first author's surname.

<xsl:template match="bibliodiv">
  <xsl:variable name="lang">
    <xsl:call-template name="l10n.language"/>
  </xsl:variable>
  <fo:block>
    <xsl:attribute name="id">
      <xsl:call-template name="object.id"/>
    </xsl:attribute>
    <xsl:call-template name="bibliodiv.titlepage"/>
    <xsl:apply-templates 
      select="*[not(self::biblioentry) and not(self::bibliomixed)]"/>
    <xsl:apply-templates select="biblioentry|bibliomixed">
      <xsl:sort select="author[1]//surname"
                lang="$lang"
                data-type="text" order="ascending"/>
    </xsl:apply-templates>
  </fo:block>
</xsl:template>

The original xsl:apply-templates was split into two. The first one processes all of the child elements of the bibliodiv that are not entries (i.e., optional introductory text elements). The second one processes all of the biblioentry and bibliomixed children, and it contains the sort clause. The sort's select attribute chooses what text to sort on, in this case the author's surname.

Note

This customization to sort a bibliography will not work when you use an external bibliography collection. That's because the placeholder bibliomixed elements do not have any data to sort on. The data is not filled in until each entry is processed, which is after the sort process. You could fake the data, though, by putting a sort string in an attribute in each dummy bibliomixed element, and then sorting on that attribute.