xref: /titanic_41/usr/src/cmd/lvm/metassist/sysfiles/volume-command.xsl (revision e4d060fb4c00d44cd578713eb9a921f594b733b8)
1<?xml version="1.0" encoding="utf-8" ?>
2
3<!--
4   * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
5   * Use is subject to license terms.
6   *
7   * CDDL HEADER START
8   *
9   * The contents of this file are subject to the terms of the
10   * Common Development and Distribution License, Version 1.0 only
11   * (the "License").  You may not use this file except in compliance
12   * with the License.
13   *
14   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
15   * or http://www.opensolaris.org/os/licensing.
16   * See the License for the specific language governing permissions
17   * and limitations under the License.
18   *
19   * When distributing Covered Code, include this CDDL HEADER in each
20   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
21   * If applicable, add the following below this CDDL HEADER, with the
22   * fields enclosed by brackets "[]" replaced with your own identifying
23   * information: Portions Copyright [yyyy] [name of copyright owner]
24   *
25   * CDDL HEADER END
26   *
27   * ident	"%Z%%M%	%I%	%E% SMI"
28   *
29   * Used by metassist(1M) to create a Bourne shell script from an XML
30   * file conforming to the volume-config DTD.
31   *
32   * See volume-config(4) for a detailed description of the volume-
33   * config syntax.
34   -->
35<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
36  <xsl:output method="text"/>
37
38  <!-- Set a default lang -->
39  <xsl:param name="lang">en</xsl:param>
40
41  <!-- The file containing localized <message> elements -->
42  <!-- Currently set to local doc until an i18n scheme is established -->
43  <xsl:variable name="msgfile" select="document('')"/>
44  <xsl:variable name="langprefix" select="substring-before($lang,'-')"/>
45
46  <!-- Root template -->
47  <xsl:template match="/">
48
49    <!-- Use Bourne shell -->
50    <xsl:text>#!/bin/sh
51
52#
53# </xsl:text>
54    <xsl:call-template name="gettext">
55      <xsl:with-param name="msgid">Environment</xsl:with-param>
56    </xsl:call-template>
57
58    <xsl:text>
59#
60
61# </xsl:text>
62    <xsl:call-template name="gettext">
63      <xsl:with-param name="msgid">Amend PATH</xsl:with-param>
64    </xsl:call-template>
65
66    <xsl:text>
67PATH="/usr/sbin:/usr/bin:$PATH"
68export PATH
69
70# </xsl:text>
71    <xsl:call-template name="gettext">
72      <xsl:with-param name="msgid">Disk set name</xsl:with-param>
73    </xsl:call-template>
74
75    <!-- Set disk set -->
76    <xsl:text>&#x0a;</xsl:text>
77    <xsl:text>diskset='</xsl:text>
78    <xsl:value-of select="//diskset/@name" />
79
80    <!-- &#x0a; is a newline entity -->
81    <xsl:text>'&#x0a;</xsl:text>
82
83    <xsl:text>
84#
85# </xsl:text>
86    <xsl:call-template name="gettext">
87      <xsl:with-param name="msgid">Functions</xsl:with-param>
88    </xsl:call-template>
89
90    <xsl:text>
91#
92
93# </xsl:text>
94    <xsl:call-template name="gettext">
95      <xsl:with-param name="msgid">Echo (verbose) and exec given command, exit on error</xsl:with-param>
96    </xsl:call-template>
97
98    <xsl:text>
99execho () {
100    test -n "$verbose" &amp;&amp; echo "$@"
101    "$@" || exit
102}
103
104# </xsl:text>
105    <xsl:call-template name="gettext">
106      <xsl:with-param name="msgid">Get full /dev/rdsk path of given slice</xsl:with-param>
107    </xsl:call-template>
108
109    <xsl:text>
110fullpath () {
111    case "$1" in
112        /dev/dsk/*|/dev/did/dsk/*) echo "$1" | sed 's/dsk/rdsk/' ;;
113        /*) echo "$1" ;;
114        *) echo /dev/rdsk/"$1" ;;
115    esac
116}
117
118# </xsl:text>
119    <xsl:call-template name="gettext">
120      <xsl:with-param name="msgid">Run fmthard, ignore partboot error, error if output</xsl:with-param>
121    </xsl:call-template>
122
123    <xsl:text>
124fmthard_special () {
125    ignore='Error writing partboot'
126    out=`fmthard "$@" 2&gt;&amp;1`
127    result=$?
128    echo "$out" |
129    case "$out" in
130        *"$ignore"*) grep -v "$ignore"; return 0 ;;
131        '') return "$result" ;;
132        *) cat; return 1 ;;
133    esac &gt;&amp;2
134}
135
136#
137# </xsl:text>
138    <xsl:call-template name="gettext">
139      <xsl:with-param name="msgid">Main</xsl:with-param>
140    </xsl:call-template>
141
142    <xsl:text>
143#
144
145# </xsl:text>
146    <xsl:call-template name="gettext">
147      <xsl:with-param name="msgid">Verify root</xsl:with-param>
148    </xsl:call-template>
149
150    <xsl:text>
151if [ "`id | sed 's/^[^(]*(\([^)]*\).*/\1/'`" != root ]
152then
153    echo "</xsl:text>
154
155    <xsl:call-template name="gettext">
156      <xsl:with-param name="msgid">This script must be run as root.</xsl:with-param>
157    </xsl:call-template>
158
159    <xsl:text>" >&amp;2
160    exit 1;
161fi
162
163# </xsl:text>
164    <xsl:call-template name="gettext">
165      <xsl:with-param name="msgid">Check for verbose option</xsl:with-param>
166    </xsl:call-template>
167
168    <xsl:text>
169case "$1" in
170    -v) verbose=1 ;;
171    *) verbose= ;;
172esac
173    </xsl:text>
174
175    <!-- Create disk set -->
176    <xsl:apply-templates select="//diskset" mode="create"/>
177
178    <!-- Format unused slices -->
179    <xsl:apply-templates select="//slice[@sizeinblocks = 0]" mode="create"/>
180
181    <!-- Add disks to set -->
182    <xsl:apply-templates select="//disk" mode="add"/>
183
184    <!-- Format used slices -->
185    <xsl:apply-templates select="//slice[@sizeinblocks != 0]" mode="create"/>
186
187    <!-- Create HSPs -->
188    <xsl:apply-templates select="//hsp" mode="create"/>
189
190    <!-- Create stripes -->
191    <xsl:apply-templates select="//stripe" mode="create"/>
192
193    <!-- Create concats -->
194    <xsl:apply-templates select="//concat" mode="create"/>
195
196    <!-- Create mirrors -->
197    <xsl:apply-templates select="//mirror" mode="create"/>
198
199  </xsl:template>
200
201  <!-- "Create disk set" template -->
202  <xsl:template match="diskset" mode="create">
203    <xsl:text>&#x0a;# </xsl:text>
204    <xsl:call-template name="gettext">
205      <xsl:with-param name="msgid">Does the disk set exist?</xsl:with-param>
206    </xsl:call-template>
207
208    <xsl:text>
209if metaset -s "$diskset" >/dev/null 2>&amp;1
210then
211    # </xsl:text>
212    <xsl:call-template name="gettext">
213      <xsl:with-param name="msgid">Take control of disk set</xsl:with-param>
214    </xsl:call-template>
215
216    <xsl:text>
217    execho metaset -s "$diskset" -t
218else
219    # </xsl:text>
220    <xsl:call-template name="gettext">
221      <xsl:with-param name="msgid">Create the disk set</xsl:with-param>
222    </xsl:call-template>
223
224    <xsl:text>
225    autotakeargs=
226    /usr/sbin/clinfo || autotakeargs='-A enable'
227    execho metaset -s "$diskset" $autotakeargs -a -h `uname -n | cut -f1 -d.`
228fi
229    </xsl:text>
230  </xsl:template>
231
232  <!-- "Add disk" template -->
233  <xsl:template match="disk" mode="add">
234    <!-- Add comment -->
235    <xsl:if test="position() = 1">
236      <xsl:text>&#x0a;# </xsl:text>
237      <xsl:call-template name="gettext">
238        <xsl:with-param name="msgid">Add disks to set</xsl:with-param>
239      </xsl:call-template>
240      <xsl:text>&#x0a;</xsl:text>
241    </xsl:if>
242
243    <!-- Output command -->
244    <xsl:call-template name="parameterize">
245      <xsl:with-param name="string">execho metaset -s "$diskset" -a {1}</xsl:with-param>
246      <xsl:with-param name="1" select="@name"/>
247    </xsl:call-template>
248
249    <xsl:text>&#x0a;</xsl:text>
250  </xsl:template>
251
252  <!-- "Create slice" template -->
253  <xsl:template match="slice" mode="create">
254
255    <!-- Add comment -->
256    <xsl:if test="position() = 1">
257      <xsl:text>&#x0a;# </xsl:text>
258      <xsl:call-template name="gettext">
259        <xsl:with-param name="msgid">Format slices</xsl:with-param>
260      </xsl:call-template>
261      <xsl:text>&#x0a;</xsl:text>
262    </xsl:if>
263
264    <!-- Does this slice have a start sector and size? -->
265    <xsl:if test="(@startsector and @sizeinblocks) or (@sizeinblocks = 0)">
266
267      <!-- Output command -->
268      <xsl:call-template name="parameterize">
269        <xsl:with-param name="string">execho fmthard_special -d {1}:{5}:0:{2}:{3} `fullpath {4}`</xsl:with-param>
270        <xsl:with-param name="1">
271          <xsl:call-template name="getslice">
272            <xsl:with-param name="device" select="@name" />
273          </xsl:call-template>
274        </xsl:with-param>
275        <xsl:with-param name="2">
276          <xsl:choose>
277            <!-- When zeroing out a slice, use 0 for start sector -->
278            <xsl:when test="@sizeinblocks = 0">0</xsl:when>
279            <!-- Otherwise, use the start sector supplied -->
280            <xsl:otherwise>
281              <xsl:value-of select="@startsector" />
282            </xsl:otherwise>
283          </xsl:choose>
284        </xsl:with-param>
285        <xsl:with-param name="3" select="@sizeinblocks" />
286        <xsl:with-param name="4" select="@name" />
287        <xsl:with-param name="5">
288          <xsl:choose>
289            <!-- When zeroing out a slice, use 0 (V_UNASSIGNED) slice tag -->
290            <xsl:when test="@sizeinblocks = 0">0</xsl:when>
291            <!-- Otherwise, use 4 (V_USR) -->
292            <xsl:otherwise>4</xsl:otherwise>
293          </xsl:choose>
294        </xsl:with-param>
295      </xsl:call-template>
296
297      <xsl:text>&#x0a;</xsl:text>
298    </xsl:if>
299  </xsl:template>
300
301  <!-- Template for a "create volume" comment -->
302  <xsl:template name="createdevcomment">
303    <!-- Indent parameter -->
304    <xsl:param name = "indent" />
305
306    <xsl:text>&#x0a;</xsl:text>
307    <xsl:value-of select="$indent" />
308    <xsl:text># </xsl:text>
309
310    <!-- Add comment -->
311    <xsl:call-template name="gettext">
312      <xsl:with-param name="msgid">Create {1} {2}</xsl:with-param>
313      <xsl:with-param name="1" select="name()"/>
314      <xsl:with-param name="2" select="@name"/>
315    </xsl:call-template>
316
317    <xsl:text>&#x0a;</xsl:text>
318  </xsl:template>
319
320  <!-- "Create hsp" template -->
321  <xsl:template match="hsp" mode="create">
322
323    <!-- Does this HSP contain slice elements? -->
324    <xsl:if test="slice">
325
326      <xsl:text>&#x0a;# </xsl:text>
327
328      <!-- Add comment -->
329      <xsl:call-template name="gettext">
330        <xsl:with-param name="msgid">Does {1} exist?</xsl:with-param>
331        <xsl:with-param name="1" select="@name"/>
332      </xsl:call-template>
333
334      <xsl:text>&#x0a;</xsl:text>
335
336      <!-- Output command to test for existence of HSP -->
337      <xsl:call-template name="parameterize">
338        <xsl:with-param name="string">metahs -s "$diskset" -i {1} >/dev/null 2>&amp;1 || {</xsl:with-param>
339        <xsl:with-param name="1" select="@name"/>
340      </xsl:call-template>
341
342      <!-- Add comment -->
343      <xsl:call-template name="createdevcomment">
344        <xsl:with-param name = "indent" xml:space="preserve">    </xsl:with-param>
345      </xsl:call-template>
346
347      <!-- Output command to create HSP -->
348      <xsl:call-template name="parameterize">
349        <xsl:with-param name="string">    execho metainit -s "$diskset" {1}</xsl:with-param>
350        <xsl:with-param name="1" select="@name"/>
351      </xsl:call-template>
352
353      <xsl:text>&#x0a;}&#x0a;&#x0a;# </xsl:text>
354
355      <!-- Add comment -->
356      <xsl:call-template name="gettext">
357        <xsl:with-param name="msgid">Add slices to {1}</xsl:with-param>
358        <xsl:with-param name="1" select="@name"/>
359      </xsl:call-template>
360
361      <xsl:text>&#x0a;</xsl:text>
362
363      <xsl:for-each select="slice">
364
365        <!-- Output command -->
366        <xsl:call-template name="parameterize">
367          <xsl:with-param name="string">execho metahs -s "$diskset" -a {1} {2}</xsl:with-param>
368          <xsl:with-param name="1" select="../@name"/>
369          <xsl:with-param name="2" select="@name"/>
370        </xsl:call-template>
371
372        <xsl:text>&#x0a;</xsl:text>
373
374      </xsl:for-each>
375    </xsl:if>
376
377  </xsl:template>
378
379  <!-- "Create stripe/concat" template -->
380  <xsl:template match="stripe|concat" mode="create">
381
382    <!-- Does this stripe/concat contain slice elements? -->
383    <xsl:if test="slice">
384
385      <!-- Add comment -->
386      <xsl:call-template name="createdevcomment"/>
387
388      <!-- Output command -->
389      <xsl:text>execho metainit -s "$diskset" </xsl:text>
390      <xsl:value-of select="@name" />
391
392      <xsl:choose>
393        <!-- Stripe-specific parameters -->
394        <xsl:when test="name() = 'stripe'">
395          <xsl:text> 1 </xsl:text>
396          <xsl:value-of select="count(slice)" />
397
398          <xsl:for-each select="slice">
399            <xsl:text> </xsl:text>
400            <xsl:value-of select="@name" />
401          </xsl:for-each>
402
403          <!-- Does this stripe contain an interlace attribute? -->
404          <xsl:if test="@interlace">
405
406            <!-- Write interlace with unit string -->
407            <xsl:variable name="interlace"
408              select="substring-before(@interlace, 'KB')"/>
409            <xsl:choose>
410              <xsl:when test="$interlace != ''">
411                <xsl:value-of select="concat(' -i ', $interlace, 'k')" />
412              </xsl:when>
413              <xsl:otherwise>
414                <xsl:variable name="interlace"
415                  select="substring-before(@interlace, 'MB')"/>
416                <xsl:choose>
417                  <xsl:when test="$interlace != ''">
418                    <xsl:value-of select="concat(' -i ', $interlace, 'm')" />
419                  </xsl:when>
420                  <xsl:otherwise>
421                    <xsl:variable name="interlace"
422                      select="substring-before(@interlace, 'BLOCKS')"/>
423                    <xsl:if test="$interlace != ''">
424                      <xsl:value-of select="concat(' -i ', $interlace, 'b')" />
425                    </xsl:if>
426                  </xsl:otherwise>
427                </xsl:choose>
428              </xsl:otherwise>
429            </xsl:choose>
430          </xsl:if>
431        </xsl:when>
432
433        <!-- Concat-specific parameters -->
434        <xsl:otherwise>
435          <xsl:text> </xsl:text>
436          <xsl:value-of select="count(slice)" />
437
438          <xsl:for-each select="slice">
439            <xsl:text> 1 </xsl:text>
440            <xsl:value-of select="@name" />
441          </xsl:for-each>
442        </xsl:otherwise>
443      </xsl:choose>
444
445      <xsl:text>&#x0a;</xsl:text>
446    </xsl:if>
447
448    <!-- Does this stripe/concat contain hsp elements? -->
449    <xsl:if test="hsp">
450
451      <xsl:text>&#x0a;# </xsl:text>
452
453      <!-- Add comment -->
454      <xsl:call-template name="gettext">
455        <xsl:with-param name="msgid">Associate {1} {2} with hot spare pool {3}</xsl:with-param>
456        <xsl:with-param name="1" select="name()"/>
457        <xsl:with-param name="2" select="@name"/>
458        <xsl:with-param name="3" select="hsp/@name"/>
459      </xsl:call-template>
460
461      <xsl:text>&#x0a;</xsl:text>
462
463      <!-- Output command -->
464      <xsl:call-template name="parameterize">
465        <xsl:with-param name="string">execho metaparam -s "$diskset" -h {1} {2}</xsl:with-param>
466        <xsl:with-param name="1" select="hsp/@name"/>
467        <xsl:with-param name="2" select="@name"/>
468      </xsl:call-template>
469
470      <xsl:text>&#x0a;</xsl:text>
471    </xsl:if>
472  </xsl:template>
473
474  <!-- "Create mirror" template -->
475  <xsl:template match="mirror" mode="create">
476    <!-- Add comment -->
477    <xsl:call-template name="createdevcomment"/>
478
479    <!-- Attach submirrors -->
480    <xsl:for-each select="stripe|concat">
481      <xsl:choose >
482        <xsl:when test="position() = 1">
483
484          <!-- Output create command -->
485          <xsl:call-template name="parameterize">
486            <xsl:with-param name="string">execho metainit -s "$diskset" {1} -m {2}</xsl:with-param>
487            <xsl:with-param name="1" select="../@name"/>
488            <xsl:with-param name="2" select="@name"/>
489          </xsl:call-template>
490
491          <!-- Read option -->
492          <xsl:choose >
493            <!-- Geometric -->
494            <xsl:when test="../@read = 'GEOMETRIC'">
495              <xsl:text> -g</xsl:text>
496            </xsl:when>
497
498            <!-- First -->
499            <xsl:when test="../@read = 'FIRST'">
500              <xsl:text> -r</xsl:text>
501            </xsl:when>
502          </xsl:choose>
503
504          <!-- Write option - serial -->
505          <xsl:if test="../@write = 'SERIAL'">
506            <xsl:text> -S</xsl:text>
507          </xsl:if>
508
509          <!-- Pass number -->
510          <xsl:if test="../@passnum">
511            <xsl:text> </xsl:text>
512            <xsl:value-of select="../@passnum" />
513          </xsl:if>
514
515          <xsl:text>&#x0a;</xsl:text>
516        </xsl:when>
517
518        <xsl:otherwise>
519          <!-- Output attach command -->
520          <xsl:call-template name="parameterize">
521            <xsl:with-param name="string">execho metattach -s "$diskset" {1} {2}</xsl:with-param>
522            <xsl:with-param name="1" select="../@name"/>
523            <xsl:with-param name="2" select="@name"/>
524          </xsl:call-template>
525
526          <xsl:text>&#x0a;</xsl:text>
527        </xsl:otherwise>
528      </xsl:choose>
529    </xsl:for-each>
530  </xsl:template>
531
532  <!-- Get the slice index from a device string -->
533  <xsl:template name="getslice">
534    <xsl:param name="device" />
535
536    <xsl:choose>
537
538      <!-- Does $device contain 's'? -->
539      <xsl:when test="contains($device, 's')">
540
541        <!-- Recurse with remaining text -->
542        <xsl:call-template name="getslice">
543          <xsl:with-param name="device" select="substring-after($device, 's')" />
544        </xsl:call-template>
545      </xsl:when>
546
547      <!-- No match -->
548      <xsl:otherwise>
549        <xsl:value-of select="$device" />
550      </xsl:otherwise>
551
552    </xsl:choose>
553  </xsl:template>
554
555  <!-- Generic (global) search and replace template -->
556  <xsl:template name="searchreplace">
557    <xsl:param name="text" />
558    <xsl:param name="search" />
559    <xsl:param name="replace" />
560
561    <xsl:choose>
562
563      <!-- Does $text contain $search? -->
564      <xsl:when test="contains($text, $search)">
565
566        <!-- Print text before match -->
567        <xsl:value-of select="substring-before($text, $search)" />
568
569        <!-- Print replaced text -->
570        <xsl:value-of select="$replace" />
571
572        <!-- Recurse with remaining text -->
573        <xsl:call-template name="searchreplace">
574          <xsl:with-param name="text" select="substring-after($text, $search)" />
575          <xsl:with-param name="search" select="$search" />
576          <xsl:with-param name="replace" select="$replace" />
577        </xsl:call-template>
578      </xsl:when>
579
580      <!-- No match -->
581      <xsl:otherwise>
582        <xsl:value-of select="$text" />
583      </xsl:otherwise>
584
585    </xsl:choose>
586  </xsl:template>
587
588  <!--
589     * Given a message ID (msgid), find a localized message string
590     * stored in $msgfile as a xsl:variable.  Return the first
591     * occurance of:
592     *
593     * 1. The message localized for the language code and country
594     *    code, ie. "en-us"
595     *
596     * 2. The message localized for a sublanguage
597     *
598     * 3. The message localized for the language code only, ie. "en"
599     *
600     * 4. The message localized for the language code, with any
601     *    country code, ie. "en-gb"
602     *
603     * 5. $msgid
604     *
605     * Parameters:
606     *
607     *    msgid: The message identification key
608     *
609     *    1, 2, 3, 4, 5: Parameters to replace "{1}", "{2}", "{3}",
610     *    "{4}", "{5}" respectively, in the retrieved message
611     -->
612  <xsl:template name="gettext">
613    <xsl:param name="msgid"/>
614    <xsl:param name="1"/>
615    <xsl:param name="2"/>
616    <xsl:param name="3"/>
617    <xsl:param name="4"/>
618    <xsl:param name="5"/>
619    <xsl:variable name="messages" select="$msgfile//message[@msgid=$msgid]"/>
620
621    <xsl:call-template name="parameterize">
622      <xsl:with-param name="1" select="$1"/>
623      <xsl:with-param name="2" select="$2"/>
624      <xsl:with-param name="3" select="$3"/>
625      <xsl:with-param name="4" select="$4"/>
626      <xsl:with-param name="5" select="$5"/>
627      <xsl:with-param name="string">
628
629        <xsl:choose>
630
631          <!-- Exact match for $lang -->
632          <xsl:when test="$messages[@xml:lang=$lang]">
633            <xsl:value-of select="$messages[@xml:lang=$lang][1]"/>
634          </xsl:when>
635
636          <!-- Sublanguage of $lang -->
637          <xsl:when test="$messages[lang($lang)]">
638            <xsl:value-of name="message" select="$messages[lang($lang)][1]"/>
639          </xsl:when>
640
641          <!-- Exact match for $langprefix -->
642          <xsl:when test="$messages[@xml:lang=$langprefix]">
643            <xsl:value-of select="$messages[@xml:lang=$langprefix][1]"/>
644          </xsl:when>
645
646          <!-- Sublanguage of $langprefix -->
647          <xsl:when test="$messages[lang($langprefix)]">
648            <xsl:value-of select="$messages[lang($langprefix)][1]"/>
649          </xsl:when>
650
651          <!-- No match found, return msgid -->
652          <xsl:otherwise>
653            <xsl:value-of select="$msgid"/>
654          </xsl:otherwise>
655
656        </xsl:choose>
657      </xsl:with-param>
658    </xsl:call-template>
659  </xsl:template>
660
661  <!-- Parameterize up to 5 parameters -->
662  <xsl:template name="parameterize">
663    <xsl:param name="string"/>
664    <xsl:param name="1"/>
665    <xsl:param name="2"/>
666    <xsl:param name="3"/>
667    <xsl:param name="4"/>
668    <xsl:param name="5"/>
669
670    <xsl:call-template name="searchreplace">
671      <xsl:with-param name="text">
672        <xsl:call-template name="searchreplace">
673          <xsl:with-param name="text">
674            <xsl:call-template name="searchreplace">
675              <xsl:with-param name="text">
676                <xsl:call-template name="searchreplace">
677                  <xsl:with-param name="text">
678                    <xsl:call-template name="searchreplace">
679                      <xsl:with-param name="text" select="$string"/>
680                      <xsl:with-param name="search">{1}</xsl:with-param>
681                      <xsl:with-param name="replace" select="$1"/>
682                    </xsl:call-template>
683                  </xsl:with-param>
684                  <xsl:with-param name="search">{2}</xsl:with-param>
685                  <xsl:with-param name="replace" select="$2"/>
686                </xsl:call-template>
687              </xsl:with-param>
688              <xsl:with-param name="search">{3}</xsl:with-param>
689              <xsl:with-param name="replace" select="$3"/>
690            </xsl:call-template>
691          </xsl:with-param>
692          <xsl:with-param name="search">{4}</xsl:with-param>
693          <xsl:with-param name="replace" select="$4"/>
694        </xsl:call-template>
695      </xsl:with-param>
696      <xsl:with-param name="search">{5}</xsl:with-param>
697      <xsl:with-param name="replace" select="$5"/>
698    </xsl:call-template>
699  </xsl:template>
700
701  <!-- Localized message strings used throughout -->
702  <xsl:template name="localization">
703    <message xml:lang="de" msgid="Sample message">Beispielanzeige</message>
704  </xsl:template>
705
706</xsl:stylesheet>
707