Difficulty: ★☆☆ (easy)
Keywords: cross-references, internal link, xref

Problem

You want to create a cross-reference from one part of your document into another.

Solution

Use the xref element for this purpose. A cross reference is a one-to-one relationship from your xref to your target. To create such a relationship you need two things:

  1. The ID of your target. This is the value of the xml:id attribute. Make sure, it points to the structure itself, not the title.

  2. The empty xref element and a linkend attribute that holds the ID of your target.

For example, you want to reference to the introduction chapter in your book. The chapter looks like this:

<chapter xml:id="intro">
  <title>Introduction</title>
  ...
</chapter>

As you can see, the chapter contains a title but most importantly, it also has a xml:id attribute. This is our “anchor” or ID.

If you want to create a cross-reference to your introduction chapter, use the xref element as follows:

<para>Get basic information in <xref linkend="intro"/>.</para>

The previous xref is rendered as follows:

Get basic information in Chapter 1. “Introduction”.

Discussion

Cross referencing is important in your documents as it makes your text accessible for your reader. The previous section showed the simplest form of a cross-reference. However, there is more to find out about xref. The following subsections give you some useful tips and tricks:

Reference to Elements with Titles Only

Basically, DocBook allows you to insert an xml:id attribute on every element. However, that does not mean, you should insert one. As you could see from the previous section, when the xref is resolved, the DocBook stylesheets use the title element to create the reference to its target. If you refer to an element where no title is allowed (for example, a para), the cross-reference cannot be resolved correctly. Depending on the version of the DocBook stylesheets, you get either an error or the xref uses the title of its nearest ancestor (for example, the parent's section containing the para).

Fine-tuning Cross-References

In cases where it is not enough to just refer to a target, use the xrefstyle attribute to fine-tune the appearance of the resolved cross-reference. The xrefstyle attribute expects one of the following values:

template: TEMPLATE_KEYWORDS

After the template:, use the % placeholders to define where title, number, etc. should appear.

select: SELECT_KEYWORDS

After the select:, use specific keywords that map to title, number, etc.

ANY_NAME

If the xrefstyle attribute does not start with either select nor template, it is interpreted as a name that can be found in a language file. This solution is not covered in this topic.

Using template

The template method contains an immutable string including placeholders. These placeholders are replaced with their actual values during transformation. For example, if you want a different text to this section than the default, you could use the following code:

Section <xref linkend="dbc.markup.xref" xrefstyle="template:%t"/> helps you with the xref element.

During transformation, the %t placeholder is replaced by the target's title:

Section Inserting Cross-References helps you with the xref element.

As you can see, any other string not starting with % is untouched and literally copied. Table 1.6, “Available Placeholders for template gives you an overview about all available placeholders.

Table 1.6. Available Placeholders for template
PlaceholderDescription
%ddirection (“above” or “below”)
%nnumber
%odocument name (only for olinks)
%ppage number, if applicable
%ssubtitle, if applicable
%ttitle
Using select

The select method expects several self-explanatory keywords that are also replaced during transformation. The difference is, that you cannot use free text as in template thus giving you less freedom. For instance, the first example in Using template can also be expressed by using select:

Section <xref linkend="dbc.markup.xref" xrefstyle="select:title"/> helps you with the xref element.

Table 1.7. Available Keywords for select
KeywordExampleDescription
Labels
labelChapter 5label and number
labelnameChaptername of the referencing element
labelnumber5only the number
Titels
titleInserting Cross-Referencestitle without quotes
quotedtitle“Inserting Cross-References”title with quotes
Pagenumber
page(page 100)page number in brackets
Page“Page 100”uppercase “page”
pageabbrev(p. 100)abbreviated page
pagenumber100only the page number
nopagen/asuppressed page number

The order of the keywords does not matter; a select:title nopage is the same as select:nopage title. The order is taken from the language files in common/. For example, the following English language file defines the order of a chapter title (number followed by the title):

<l:context name="title-numbered">
  <l:template name="article/appendix" text="%n. %t"/>
</l:context>

Using xreflabel Only in Rare Cases

In rare cases, you have to refer to an element that does not allow a title. For example, if you want to refer to a paragraph. In such a case, use the xreflabel.

For example, if you refer to this paragraph with an ID of _para1, your xref will be resolved as follows:

<xref linkend="_para1"/>: the section called “Using xreflabel Only in Rare Cases”

As you can see, it prints the title of its ancestor element. However, if you add a xreflabel to this paragraph, you will end up with this:

<para xml:id="_para2" xreflabel="A better test"> ... <para
...
<xref linkend="_para2"/>: A better test

Remember, this should not be your default markup when cross referencing. Always try to refer to an element that contains a title as noted in the section called “Reference to Elements with Titles Only”.

Watch For Language Pitfalls

When using xrefs, it can be sometimes difficult to write a “fluent” sentence. For example, you could be inclined to start a sentence like this:

The following chapter <xref linkend="dbc.markup"/> explains...

However, the output is undesireable:

The following chapter Chapter 1, Knowing DocBook’s Structure explains...

Removing the word “chapter” makes it less ugly, but the problem still persists: how to create fluent, easy to read sentences where cross-references are nicely resolved?

One solution is to rewrite the sentence and start with the xref:

<xref linkend="dbc.markup"/> explains ...

If you do not like this style, you can switch to passive voice as another solution:

The topic ABC is explained in <xref linkend="dbc.markup"/>.

Sometimes passive voice is not appropriate. In cases where you do not want to change the grammatical voice, use the template or select methods. Applied to the first example, you can rewrite the xref with xrefstyle:

The following <xref linkend="dbc.markup" xrefstyle="chapter %t"/>, explains...

See Also


Project@GitHubIssue#6