Перейти к содержанию

xsl:apply-templates

Элемент xsl:apply-templates применяет шаблонные правила к узлам, которые возвращаются выражением, указанным в атрибуте select.

Если атрибут select опущен, то xsl:apply-templates применяет шаблонные правила ко всем дочерним узлам текущего узла.

Синтаксис

1
2
3
<xsl:apply-templates select="выражение" mode="режим">
  <!-- Content: (xsl:sort | xsl:with-param)* -->
</xsl:apply-templates>

Атрибуты:

select
необязательный атрибут, выражение вычисляет набор узлов к которым применяются преобразования. Если атрибут не задан — преобразования применяются ко всем потомкам текущего узла, включая текстовые.
mode
необязательный атрибут, указывает имя режима преобразования.

Описание и примеры

Пример 1

В примере 1 для элемента chapter создается блок, а затем обрабатывается его непосредственный потомок:

1
2
3
4
5
<xsl:template match="chapter">
  <fo:block>
    <xsl:apply-templates />
  </fo:block>
</xsl:template>

Пример 2

В примере 2 обрабатываются все содержащиеся в author элементы given-name, которые являются непосредственным потомком author-group:

1
2
3
4
5
<xsl:template match="author-group">
  <fo:inline-sequence>
    <xsl:apply-templates select="author/given-name" />
  </fo:inline-sequence>
</xsl:template>

Пример 3

В примере 3 обрабатываются все элементы heading, являющиеся потомками элемента book:

1
2
3
4
5
<xsl:template match="book">
  <fo:block>
    <xsl:apply-templates select=".//heading" />
  </fo:block>
</xsl:template>

Пример 4

Есть также возможность обрабатывать элементы, которые не являются потомками текущего узла. В примере 4 предполагается, что элемент department имеет непосредственный потомок group и потомки employee. Сперва находится отдел employee, а затем обрабатывается непосредственный потомок group элемента department:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<xsl:template match="employee">
  <fo:block>
    Employee
    <xsl:apply-templates select="name" />
    belongs to group
    <xsl:apply-templates
      select="ancestor::department/group"
    />
  </fo:block>
</xsl:template>

Пример 5

Для выполнения простого переупорядочения в пределах одного шаблона можно использовать сразу несколько элементов xsl:apply-templates. В примере 5 создаются две таблицы HTML. Первая таблица заполняется отечественными продажами, вторая — международными:

1
2
3
4
5
6
7
8
<xsl:template match="product">
  <table>
    <xsl:apply-templates select="sales/domestic" />
  </table>
  <table>
    <xsl:apply-templates select="sales/foreign" />
  </table>
</xsl:template>

В XSLT 2.0 у атрибута mode при использовании с элементом <xsl:apply-templates> появились два специальных значения:

  • #default – соответствует режиму по умолчанию;
  • #current – соответствует текущему режиму.

В XSLT 2.0 возможности атрибута mode были расширены. В следующей таблице стилей используются значения #default, #current и #all атрибута mode:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<?xml version="1.0" encoding="utf-8" ?>
<!-- apply-templates2.xsl -->
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0"
>
  <xsl:output method="html" />
  <xsl:template match="/">
    <html>
      <head>
        <title>Using the mode attribute</title>
      </head>
      <body style="font-family: sans-serif;">
        <table style="text-align: center;" border="1">
          <tr style="font-weight: bold; font-size: 150%;">
            <td width="30%">Default mode</td>
            <td width="30%">Blue mode</td>
            <td width="30%">Red mode</td>
          </tr>
          <tr>
            <td>
              <p>
                <xsl:apply-templates
                  mode="#default"
                  select="/cars/manufacturer"
                />
              </p>
            </td>
            <td>
              <p>
                <xsl:apply-templates
                  mode="blue"
                  select="/cars/manufacturer"
                />
              </p>
            </td>
            <td>
              <p>
                <xsl:apply-templates
                  mode="red"
                  select="/cars/manufacturer"
                />
              </p>
            </td>
          </tr>
        </table>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="manufacturer">
    <div
      style="color: green; font-style: italic; font-size: 125%"
    >
      <xsl:apply-templates select="car" mode="#current" />
    </div>
  </xsl:template>
  <xsl:template match="manufacturer" mode="blue red">
    <div style="color: blue; font-weight: bold;">
      <xsl:apply-templates select="car" mode="#current" />
    </div>
  </xsl:template>
  <xsl:template match="car" mode="#all">
    <xsl:value-of select="." />
    <br />
  </xsl:template>
  <xsl:template match="car" mode="red" priority="1">
    <div
      style="color: red; font-size: 125%; font-family: serif;"
    >
      <xsl:value-of select="." />
      <br />
    </div>
  </xsl:template>
</xsl:stylesheet>

В XSLT 2.0 атрибут mode элемента <xsl:apply-templates> может принимать новые значения #current и #default. У атрибута mode элемента <xsl:template> определены новые значения #all и #default. В нашей таблице стилей используются все три новых значения:

  • В шаблоне match="/" элемент <xsl:apply-templates> используется со значениями #default, blue и red. Три элемента <xsl:apply-template> отличаются только одним – значением атрибута mode.
  • Первый шаблон match="manufacturer" не имеет атрибута mode, поэтому он применяется в режиме по умолчанию. При использовании <xsl:apply-templates mode="#default" ...> будет активизирован именно этот шаблон.
  • У второго шаблона match="manufacturer" атрибут mode равен blue red. Этот шаблон активизируется при выборе режима blue или red.
  • Оба шаблона match="manufacturer" используют запись <xsl:apply-templates mode="#current" ...> для обработки элементов <car>. Фактически текущее значение mode передается процессору XSLT в виде параметра, сообщая ему, какой шаблон следует применять.
  • Первый шаблон match="car" определяется с атрибутом mode="#all", поэтому он является шаблоном по умолчанию, который активизируется обоими элементами <xsl:apply-templates mode="#current" ...>.
  • Последний шаблон match="car" определяется с атрибутом mode="red". Чтобы ему отдавалось предпочтение перед шаблоном mode="#all", мы добавляем атрибут priority="1". Без него процессор Saxon выводит предупреждение о неоднозначном применении правил, хотя и активизирует шаблон mode="red" при действующем режиме red. Ядро Altova XML никаких предупреждений не выдает – оно просто активизирует шаблон с mode="red".

Начиная с шаблона match="/", наша таблица стилей генерирует выходной документ вызовами разных шаблонов с тремя режимами mode. Три режима форматируют одну и ту же информацию тремя разными способами. В итоге таблица стилей создает тот же документ HTML, что и предыдущая таблица стилей.

Пример 6

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="applyt.xsl" ?>
<customers>
  <customer>
    <name>John Smith</name>
    <address>123 Oak St.</address>
    <state>WA</state>
    <phone>(206) 123-4567</phone>
  </customer>
  <customer>
    <name>Zack Zwyker</name>
    <address>368 Elm St.</address>
    <state>WA</state>
    <phone>(206) 423-4537</phone>
  </customer>
  <customer>
    <name>Albert Aikens</name>
    <address>368 Elm St.</address>
    <state>WA</state>
    <phone>(206) 423-4537</phone>
  </customer>
  <customer>
    <name>Albert Gandy</name>
    <address>6984 4th St.</address>
    <state>WA</state>
    <phone>(206) 433-4547</phone>
  </customer>
  <customer>
    <name>Peter Furst</name>
    <address>456 Pine Av.</address>
    <state>CA</state>
    <phone>(209) 765-4321</phone>
  </customer>
  <customer>
    <name>Dan Russell</name>
    <address>9876 Main St.</address>
    <state>PA</state>
    <phone>(323) 321-7654</phone>
  </customer>
</customers>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?xml version="1.0" ?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
  <xsl:template match="/">
    <HTML>
      <BODY>
        <TABLE border="1" cellspacing="0" cellpadding="2">
          <xsl:apply-templates select="customers/customer">
            <xsl:sort select="state" />
            <xsl:sort select="name" />
          </xsl:apply-templates>
        </TABLE>
      </BODY>
    </HTML>
  </xsl:template>
  <xsl:template match="customer">
    <TR>
      <xsl:apply-templates select="name" />
      <xsl:apply-templates select="address" />
      <xsl:apply-templates select="state" />
      <xsl:apply-templates select="phone" />
      <xsl:apply-templates
        select="phone"
        mode="accountNumber"
      />
    </TR>
  </xsl:template>
  <xsl:template match="name">
    <TD STYLE="font-size:14pt font-family:serif">
      <xsl:apply-templates />
    </TD>
  </xsl:template>
  <xsl:template match="address">
    <TD>
      <xsl:apply-templates />
    </TD>
  </xsl:template>
  <xsl:template match="state">
    <TD>
      <xsl:apply-templates />
    </TD>
  </xsl:template>
  <xsl:template match="phone">
    <TD>
      <xsl:apply-templates />
    </TD>
  </xsl:template>
  <xsl:template match="phone" mode="accountNumber">
    <TD STYLE="font-style:italic">
      1-
      <xsl:value-of select="." />
      -001
    </TD>
  </xsl:template>
</xsl:stylesheet>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<html>
  <body>
    <table border="1" cellspacing="0" cellpadding="2">
      <tr>
        <td style="font-size:14pt; font-family:serif">Peter Furst</td>
        <td>456 Pine Av.</td>
        <td>CA</td>
        <td>(209) 765-4321</td>
        <td style="font-style:italic">
          1-(209) 765-4321-001
        </td>
      </tr>
      <tr>
        <td style="font-size:14pt; font-family:serif">Dan Russell</td>
        <td>9876 Main St.</td>
        ...
      </tr>
    </table>
  </body>
</html>

См. также

  • xsl:call-template — вызывает шаблон по имени.
  • xsl:sort — позволяет сортировать множество узлов.
  • xsl:with-param — связывает с именем параметра значение.
  • xsl:template — определяет шаблон.

Ссылки

Комментарии