Imported Upstream version 1.78.1
[platform/upstream/docbook-xsl-stylesheets.git] / assembly / assemble.xsl
1 <?xml version="1.0" encoding="utf-8"?>
2 <xsl:stylesheet 
3   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
4   xmlns:exsl="http://exslt.org/common"
5   xmlns:xlink="http://www.w3.org/1999/xlink"
6   xmlns="http://docbook.org/ns/docbook"
7   exclude-result-prefixes="exsl d xlink"
8   version="1.0">
9
10 <!-- $Id: assemble.xsl,v 1.10 2012-04-10 07:56:58 bobs Exp $ -->
11
12 <xsl:preserve-space elements="*"/>
13 <xsl:strip-space elements="d:assembly d:structure d:module d:resources d:resource"/>
14
15 <xsl:key name="id" match="*" use="@id|@xml:id"/>
16
17
18 <xsl:param name="docbook.version">5.0</xsl:param>
19 <xsl:param name="root.default.renderas">book</xsl:param>
20 <xsl:param name="topic.default.renderas">section</xsl:param>
21
22 <xsl:param name="output.type" select="''"/>
23 <xsl:param name="output.format" select="''"/>
24 <!-- May be used to select one structure among several to  process -->
25 <xsl:param name="structure.id" select="''"/>
26
27
28 <!-- default mode is to copy all content nodes -->
29 <xsl:template match="node()|@*" priority="-5" mode="copycontent">
30   <xsl:param name="omittitles"/>
31     <xsl:copy>
32       <xsl:apply-templates select="@*" mode="copycontent"/>
33       <xsl:apply-templates mode="copycontent">
34         <xsl:with-param name="omittitles" select="$omittitles"/>
35       </xsl:apply-templates>
36    </xsl:copy>
37 </xsl:template>
38
39 <xsl:template match="processing-instruction('oxygen')"/>
40
41 <!-- skip assembly info elements -->
42 <xsl:template match="d:info"/>
43
44 <!-- including for structure info element -->
45 <xsl:template match="d:structure/d:info"/>
46
47 <!-- handle omittitles, but only top level title of resource -->
48 <xsl:template match="/*/d:title 
49                    | /*/d:info/d:title 
50                    | /*/d:subtitle  
51                    | /*/d:info/d:subtitle
52                    | /*/d:titleabbrev  
53                    | /*/d:info/d:titleabbrev"
54               mode="copycontent">
55   <xsl:param name="omittitles"/>
56
57   <xsl:choose>
58     <xsl:when test="$omittitles = 'yes' or $omittitles = 'true' or $omittitles = '1'">
59       <!-- omit it -->
60     </xsl:when>
61     <xsl:otherwise>
62       <xsl:copy>
63         <xsl:apply-templates select="@*" mode="copycontent"/>
64         <xsl:apply-templates mode="copycontent"/>
65       </xsl:copy>
66     </xsl:otherwise>
67   </xsl:choose>
68 </xsl:template>
69
70 <!-- handled in a mode -->
71 <xsl:template match="d:resources"/>
72 <xsl:template match="d:output|d:filterin|d:filterout|d:merge|d:revhistory"/>
73 <xsl:template match="d:output|d:filterin|d:filterout|d:merge|d:revhistory"
74               mode="copycontent"/>
75
76 <xsl:template match="d:assembly">
77   <xsl:choose>
78     <xsl:when test="$structure.id != ''">
79       <xsl:variable name="id.structure" select="key('id', $structure.id)"/>
80       <xsl:choose>
81         <xsl:when test="count($id.structure) = 0">
82           <xsl:message terminate="yes">
83             <xsl:text>ERROR: structure.id param set to '</xsl:text>
84             <xsl:value-of select="$structure.id"/>
85             <xsl:text>' but no element with that xml:id exists in assembly.</xsl:text>
86           </xsl:message>
87         </xsl:when>
88         <xsl:when test="local-name($id.structure) != 'structure'">
89           <xsl:message terminate="yes">
90             <xsl:text>ERROR: structure.id param set to '</xsl:text>
91             <xsl:value-of select="$structure.id"/>
92             <xsl:text>' but no structure with that xml:id exists in assembly.</xsl:text>
93           </xsl:message>
94         </xsl:when>
95         <xsl:otherwise>
96           <xsl:apply-templates select="key('id', $structure.id)"/>
97         </xsl:otherwise>
98       </xsl:choose>
99     </xsl:when>
100     <xsl:when test="$output.type != '' and not(d:structure[@type = $output.type])">
101       <xsl:message terminate="yes">
102         <xsl:text>ERROR: output.type param set to '</xsl:text>
103         <xsl:value-of select="$output.type"/>
104         <xsl:text> but no structure element has that type attribute. Exiting.</xsl:text>
105       </xsl:message>
106     </xsl:when>
107     <xsl:when test="$output.type != '' and d:structure[@type = $output.type]">
108       <xsl:apply-templates select="d:structure[@type = $output.type][1]"/>
109     </xsl:when>
110     <xsl:otherwise>
111       <!-- otherwise process the first structure -->
112       <xsl:apply-templates select="d:structure[1]"/>
113     </xsl:otherwise>
114   </xsl:choose>
115 </xsl:template>
116
117 <xsl:template match="d:structure[not(@resourceref)]">
118
119   <xsl:variable name="output.root.element">
120     <xsl:apply-templates select="." mode="compute.element.name"/>
121   </xsl:variable>
122
123   <xsl:element name="{$output.root.element}" namespace="http://docbook.org/ns/docbook">
124     <xsl:attribute name="version">
125       <xsl:value-of select="$docbook.version"/>
126     </xsl:attribute>
127     <xsl:copy-of select="@xml:id"/>
128
129     <xsl:apply-templates> 
130       <xsl:with-param name="parent" select="$output.root.element"/>
131     </xsl:apply-templates>
132
133   </xsl:element>
134 </xsl:template>
135
136 <xsl:template match="d:glossary|d:bibliography|d:index|d:toc">
137    <xsl:param name="parent" select="''"/>
138   <xsl:apply-templates select="." mode="copycontent"/>
139 </xsl:template>
140
141 <xsl:template match="d:title|d:titleabbrev|d:subtitle">
142    <xsl:param name="parent" select="''"/>
143   <xsl:apply-templates select="." mode="copycontent"/>
144 </xsl:template>
145
146 <!-- module without a resourceref creates an element -->
147 <xsl:template match="d:module[not(@resourceref)]">
148   <xsl:param name="parent" select="''"/>
149   
150   <xsl:variable name="module" select="."/>
151
152   <xsl:variable name="element.name">
153     <xsl:apply-templates select="." mode="compute.element.name"/>
154   </xsl:variable>
155
156   <xsl:element name="{$element.name}" namespace="http://docbook.org/ns/docbook">
157     <xsl:choose>
158       <!-- Use the module's xml:id if it has one -->
159       <xsl:when test="@xml:id">
160         <xsl:attribute name="xml:id">
161           <xsl:value-of select="@xml:id"/>
162         </xsl:attribute>
163       </xsl:when>
164     </xsl:choose>
165
166     <xsl:call-template name="merge.info">
167       <xsl:with-param name="merge.element" select="$module/d:merge"/>
168     </xsl:call-template>
169       
170     <xsl:apply-templates>
171       <xsl:with-param name="parent" select="$element.name"/>
172     </xsl:apply-templates>
173
174   </xsl:element>
175 </xsl:template>
176
177 <xsl:template name="compute.renderas">
178   <xsl:variable name="output.value">
179     <xsl:call-template name="compute.output.value">
180       <xsl:with-param name="property">renderas</xsl:with-param>
181     </xsl:call-template>
182   </xsl:variable>
183
184   <xsl:value-of select="$output.value"/>
185
186 </xsl:template>
187
188 <!-- This utility template is passed a value for output format
189      and the name of a property and computes the value
190      of the property from output children of context element -->
191 <xsl:template name="compute.output.value">
192   <xsl:param name="property" select="''"/>
193   
194   <xsl:variable name="default.format"
195                 select="ancestor::d:structure/@defaultformat"/>
196
197   <xsl:variable name="property.value">
198     <xsl:choose>
199       <!-- if a child output element has a format that matches the param value 
200            and it has that property -->
201       <!-- The format attribute can be multivalued -->
202       <xsl:when test="$output.format != '' and 
203                       d:output[contains(concat(' ', normalize-space(@format), ' '),  
204                                  $output.format)]
205                         [@*[local-name() = $property]]">
206         <xsl:value-of 
207            select="d:output[contains(concat(' ', normalize-space(@format), ' '), 
208                               $output.format)]
209                            [@*[local-name() = $property]][1]
210                            /@*[local-name() = $property]"/>
211       </xsl:when>
212       <!-- try with the structure's @defaultformat -->
213       <xsl:when test="$default.format != '' and 
214                       d:output[contains(concat(' ', normalize-space(@format), ' '),  
215                                  $default.format)]
216                         [@*[local-name() = $property]]">
217         <xsl:value-of 
218            select="d:output[contains(concat(' ', normalize-space(@format), ' '), 
219                               $default.format)]
220                            [@*[local-name() = $property]][1]
221                            /@*[local-name() = $property]"/>
222       </xsl:when>
223       <!-- try the first output with the property-->
224       <xsl:when test="d:output[@*[local-name() = $property]]">
225         <xsl:value-of 
226            select="d:output[@*[local-name() = $property]][1]
227                            /@*[local-name() = $property]"/>
228       </xsl:when>
229       <!-- and try the module element itself -->
230       <xsl:when test="@*[local-name() = $property]">
231         <xsl:value-of 
232            select="@*[local-name() = $property]"/>
233       </xsl:when>
234     </xsl:choose>
235   </xsl:variable>
236
237   <xsl:value-of select="$property.value"/>
238 </xsl:template>
239
240 <xsl:template match="d:module[not(@resourceref)]" mode="compute.element.name">
241
242   <xsl:variable name="renderas">
243     <xsl:call-template name="compute.renderas"/>
244   </xsl:variable>
245
246   <xsl:choose>
247     <xsl:when test="string-length($renderas) != 0">
248       <xsl:value-of select="$renderas"/>
249     </xsl:when>
250     <xsl:otherwise>
251       <xsl:message terminate="yes">
252         <xsl:text>ERROR: cannot determine output element name for </xsl:text>
253         <xsl:text>module with no @resourceref and no @renderas. Exiting.</xsl:text>
254       </xsl:message>
255     </xsl:otherwise>
256   </xsl:choose>
257 </xsl:template>
258
259 <xsl:template match="d:module[@resourceref]" mode="compute.element.name">
260   <xsl:param name="ref.name" select="''"/>
261
262   <xsl:variable name="renderas">
263     <xsl:call-template name="compute.renderas"/>
264   </xsl:variable>
265
266   <xsl:choose>
267     <xsl:when test="string-length($renderas) != 0">
268       <xsl:value-of select="$renderas"/>
269     </xsl:when>
270     <xsl:when test="$ref.name = 'topic' and 
271                     string-length($topic.default.renderas) != 0"> 
272       <xsl:value-of select="$topic.default.renderas"/>
273     </xsl:when>
274     <xsl:when test="string-length($ref.name) != 0">
275       <xsl:value-of select="$ref.name"/> 
276     </xsl:when>
277     <xsl:otherwise>
278       <xsl:message terminate="yes">
279         <xsl:text>ERROR: cannot determine output element name for </xsl:text>
280         <xsl:text>@resourceref="</xsl:text>
281         <xsl:value-of select="@resourceref"/>
282         <xsl:text>". Exiting.</xsl:text>
283       </xsl:message>
284     </xsl:otherwise>
285   </xsl:choose>
286 </xsl:template>
287
288 <xsl:template match="d:structure" mode="compute.element.name">
289   <xsl:param name="ref.name" select="''"/>
290
291   <xsl:variable name="renderas">
292     <xsl:call-template name="compute.renderas"/>
293   </xsl:variable>
294
295   <xsl:choose>
296     <xsl:when test="string-length($renderas) != 0">
297       <xsl:value-of select="$renderas"/>
298     </xsl:when>
299     <xsl:when test="string-length($ref.name) != 0">
300       <xsl:value-of select="$ref.name"/> 
301     </xsl:when>
302     <xsl:when test="string-length($root.default.renderas) != 0">
303       <xsl:value-of select="$root.default.renderas"/>
304     </xsl:when>
305     <xsl:otherwise>
306       <xsl:message terminate="yes">
307         <xsl:text>ERROR: cannot determine output element name for </xsl:text>
308         <xsl:text>structure with no @renderas and no $root.default.renderas. </xsl:text>
309         <xsl:text>Exiting.</xsl:text>
310       </xsl:message>
311     </xsl:otherwise>
312   </xsl:choose>
313 </xsl:template>
314
315 <xsl:template match="d:module[@resourceref] | d:structure[@resourceref]">
316   <xsl:param name="parent" select="''"/>
317
318   <xsl:variable name="module" select="."/>
319   <xsl:variable name="resourceref" select="@resourceref"/>
320   <xsl:variable name="resource" select="key('id', $resourceref)"/>
321
322   <xsl:choose>
323     <xsl:when test="not($resource)">
324       <xsl:message terminate="yes">
325         <xsl:text>ERROR: no xml:id matches @resourceref = '</xsl:text>
326         <xsl:value-of select="$resourceref"/>
327         <xsl:text>'.</xsl:text>
328       </xsl:message>
329     </xsl:when>
330     <xsl:when test="not($resource/self::d:resource)">
331       <xsl:message terminate="yes">
332         <xsl:text>ERROR: xml:id matching @resourceref = '</xsl:text>
333         <xsl:value-of select="$resourceref"/>
334         <xsl:text> is not a resource element'.</xsl:text>
335       </xsl:message>
336     </xsl:when>
337   </xsl:choose>
338
339   <xsl:variable name="fileref.att" select="$resource/@fileref"/>
340
341   <xsl:variable name="fragment.id">
342     <xsl:if test="contains($fileref.att, '#')">
343       <xsl:value-of select="substring-after($fileref.att, '#')"/>
344     </xsl:if>
345   </xsl:variable>
346
347   <xsl:variable name="filename">
348     <xsl:choose>
349       <xsl:when test="string-length($fragment.id) != 0">
350         <xsl:value-of select="substring-before($fileref.att, '#')"/>
351       </xsl:when>
352       <xsl:otherwise>
353         <xsl:value-of select="$fileref.att"/>
354       </xsl:otherwise>
355     </xsl:choose>
356   </xsl:variable>
357
358   <xsl:variable name="fileref">
359     <xsl:choose>
360       <xsl:when test="$resource/ancestor::d:resources/@xml:base">
361         <xsl:value-of 
362             select="concat($resource/ancestor::d:resources[@xml:base][1]/@xml:base,
363                                  '/', $filename)"/>
364       </xsl:when>
365       <xsl:otherwise>
366         <xsl:value-of select="$filename"/>
367       </xsl:otherwise>
368     </xsl:choose>
369   </xsl:variable>
370
371   <xsl:choose>
372     <xsl:when test="string-length($fileref) = 0">
373       <!-- A resource without @fileref gets its content copied -->
374       <xsl:apply-templates select="$resource/node()" mode="copycontent"/>
375     </xsl:when>
376     <xsl:otherwise>
377
378       <xsl:variable name="ref.file.content" select="document($fileref,/)"/>
379     
380       <!-- selects root or fragmeht depending on if $fragment is blank -->
381       <xsl:variable name="ref.content"
382         select="$ref.file.content/*[1][$fragment.id = ''] |
383                 $ref.file.content/*[1][$fragment.id != '']/
384                    descendant-or-self::*[@xml:id = $fragment.id]"/>
385         
386       <xsl:if test="count($ref.content) = 0">
387         <xsl:message terminate="yes">
388           <xsl:text>ERROR: @fileref = '</xsl:text>
389           <xsl:value-of select="$fileref"/>
390           <xsl:text>' has no content or is unresolved.</xsl:text>
391         </xsl:message>
392       </xsl:if>
393
394       <xsl:variable name="element.name">
395         <xsl:apply-templates select="." mode="compute.element.name">
396           <xsl:with-param name="ref.name" select="local-name($ref.content)"/>
397         </xsl:apply-templates>
398       </xsl:variable>
399
400       <xsl:variable name="omittitles.property">
401         <xsl:call-template name="compute.output.value">
402           <xsl:with-param name="property">omittitles</xsl:with-param>
403         </xsl:call-template>
404       </xsl:variable>
405     
406       <xsl:variable name="contentonly.property">
407         <xsl:call-template name="compute.output.value">
408           <xsl:with-param name="property">contentonly</xsl:with-param>
409         </xsl:call-template>
410       </xsl:variable>
411     
412       <xsl:choose>
413         <xsl:when test="$contentonly.property = 'true' or 
414                         $contentonly.property = 'yes' or
415                         $contentonly.property = '1'">
416           <xsl:apply-templates select="$ref.content/node()" mode="copycontent">
417             <xsl:with-param name="omittitles" select="$omittitles.property"/>
418           </xsl:apply-templates>
419         </xsl:when>
420         <!-- use xsl:copy if using the ref element itself to get its namespaces -->
421         <xsl:when test="$element.name = local-name($ref.content)">
422           <!-- must use for-each to set context node for xsl:copy -->
423           <xsl:for-each select="$ref.content">
424             <xsl:copy>
425               <xsl:copy-of select="@*[not(name() = 'xml:id')]"/>
426               <xsl:choose>
427                 <!-- Use the module's xml:id if it has one -->
428                 <xsl:when test="$module/@xml:id">
429                   <xsl:attribute name="xml:id">
430                     <xsl:value-of select="$module/@xml:id"/>
431                   </xsl:attribute>
432                 </xsl:when>
433                 <!-- otherwise use the resource's id -->
434                 <xsl:otherwise>
435                   <xsl:copy-of select="@xml:id"/>
436                 </xsl:otherwise>
437               </xsl:choose>
438           
439               <xsl:call-template name="merge.info">
440                 <xsl:with-param name="merge.element" select="$module/d:merge"/>
441                 <xsl:with-param name="ref.content" select="$ref.content"/>
442                 <xsl:with-param name="omittitles" select="$omittitles.property"/>
443               </xsl:call-template>
444       
445               <!-- copy through all but titles, which moved to info -->
446               <xsl:apply-templates select="node()
447                        [not(local-name() = 'title') and
448                         not(local-name() = 'subtitle') and
449                         not(local-name() = 'info') and
450                         not(local-name() = 'titleabbrev')]" mode="copycontent"/>
451           
452               <xsl:apply-templates select="$module/node()"> 
453                 <xsl:with-param name="parent" select="$element.name"/>
454               </xsl:apply-templates>
455             </xsl:copy>
456           </xsl:for-each>
457         </xsl:when>
458         <xsl:otherwise>
459           <!-- create the element instead of copying it -->
460           <xsl:element name="{$element.name}" namespace="http://docbook.org/ns/docbook">
461             <xsl:copy-of select="$ref.content/@*[not(name() = 'xml:id')]"/>
462             <xsl:choose>
463               <!-- Use the module's xml:id if it has one -->
464               <xsl:when test="@xml:id">
465                 <xsl:attribute name="xml:id">
466                   <xsl:value-of select="@xml:id"/>
467                 </xsl:attribute>
468               </xsl:when>
469               <!-- otherwise use the resource's id -->
470               <xsl:when test="$ref.content/@xml:id">
471                 <xsl:attribute name="xml:id">
472                   <xsl:value-of select="$ref.content/@xml:id"/>
473                 </xsl:attribute>
474               </xsl:when>
475             </xsl:choose>
476         
477             <xsl:call-template name="merge.info">
478               <xsl:with-param name="merge.element" select="d:merge"/>
479               <xsl:with-param name="ref.content" select="$ref.content"/>
480               <xsl:with-param name="omittitles" select="$omittitles.property"/>
481             </xsl:call-template>
482     
483             <!-- copy through all but titles, which moved to info -->
484             <xsl:apply-templates select="$ref.content/node()
485                      [not(local-name() = 'title') and
486                       not(local-name() = 'subtitle') and
487                       not(local-name() = 'info') and
488                       not(local-name() = 'titleabbrev')]" mode="copycontent"/>
489         
490             <xsl:apply-templates> 
491               <xsl:with-param name="parent" select="$element.name"/>
492             </xsl:apply-templates>
493           </xsl:element>
494         </xsl:otherwise>
495       </xsl:choose>
496     </xsl:otherwise>
497   </xsl:choose>
498 </xsl:template>
499
500 <xsl:template name="merge.info">
501   <xsl:param name="merge.element" select="NOTANODE"/>
502   <xsl:param name="ref.content" select="NOTANODE"/>
503   <xsl:param name="omittitles"/> 
504
505   <!-- a merge element may use resourceref as well as literal content -->
506   <!-- any literal content overrides the merge resourceref content -->
507   <xsl:variable name="merge.ref.content">
508     <xsl:if test="$merge.element/@resourceref">
509       <xsl:variable name="resourceref" select="$merge.element/@resourceref"/>
510       <xsl:variable name="resource" select="key('id', $resourceref)"/>
511
512       <xsl:choose>
513         <xsl:when test="not($resource)">
514           <xsl:message terminate="yes">
515             <xsl:text>ERROR: no xml:id matches @resourceref = '</xsl:text>
516             <xsl:value-of select="$resourceref"/>
517             <xsl:text>'.</xsl:text>
518           </xsl:message>
519         </xsl:when>
520         <xsl:when test="not($resource/self::d:resource)">
521           <xsl:message terminate="yes">
522             <xsl:text>ERROR: xml:id matching @resourceref = '</xsl:text>
523             <xsl:value-of select="$resourceref"/>
524             <xsl:text> is not a resource element'.</xsl:text>
525           </xsl:message>
526         </xsl:when>
527       </xsl:choose>
528
529       <xsl:variable name="fileref.att" select="$resource/@fileref"/>
530
531       <xsl:variable name="fileref">
532         <xsl:choose>
533           <xsl:when test="$resource/ancestor::d:resources/@xml:base">
534             <xsl:value-of 
535                 select="concat($resource/ancestor::d:resources[@xml:base][1]/@xml:base,
536                                '/', $fileref.att)"/>
537           </xsl:when>
538           <xsl:otherwise>
539             <xsl:value-of select="$fileref.att"/>
540           </xsl:otherwise>
541         </xsl:choose>
542       </xsl:variable>
543
544       <xsl:if test="string-length($fileref) != 0">
545         <xsl:copy-of select="document($fileref,/)"/>
546       </xsl:if>
547     </xsl:if>
548   </xsl:variable>
549
550   <xsl:variable name="merge.ref.info" 
551                 select="exsl:node-set($merge.ref.content)//d:info[1]"/>
552
553   <xsl:if test="$merge.element/@resourceref and not($merge.ref.info)">
554     <xsl:message terminate="yes">
555       <xsl:text>ERROR: merge element with resourceref '</xsl:text>
556       <xsl:value-of select="$merge.element/@resourceref"/>
557       <xsl:text>' must point to something with an info element.'</xsl:text>
558     </xsl:message>
559   </xsl:if>
560
561   <xsl:variable name="omittitles.boolean">
562     <xsl:choose>
563       <xsl:when test="$omittitles = 'yes' or $omittitles = 'true' or omittitles = '1'">
564         <xsl:value-of select="1"/>
565       </xsl:when>
566       <xsl:otherwise>
567         <xsl:value-of select="0"/>
568       </xsl:otherwise>
569     </xsl:choose>
570   </xsl:variable>
571   <!-- output info if there is any -->
572   <xsl:if test="$merge.element/node() or 
573                 $merge.ref.info/node() or
574                 $ref.content/d:info/node() or
575                 $ref.content/d:title[$omittitles.boolean = 0] or
576                 $ref.content/d:subtitle[$omittitles.boolean = 0] or
577                 $ref.content/d:titleabbrev[$omittitles.boolean = 0]">
578
579     <xsl:variable name="ref.info" select="$ref.content/d:info"/>
580     <xsl:variable name="ref.title" select="$ref.content/d:title"/>
581     <xsl:variable name="ref.subtitle" select="$ref.content/d:subtitle"/>
582     <xsl:variable name="ref.titleabbrev" select="$ref.content/d:titleabbrev"/>
583     <xsl:variable name="ref.info.title" select="$ref.content/d:info/d:title"/>
584     <xsl:variable name="ref.info.subtitle" select="$ref.content/d:info/d:subtitle"/>
585     <xsl:variable name="ref.info.titleabbrev" select="$ref.content/d:info/d:titleabbrev"/>
586
587     <info>
588       <!-- First copy through any merge attributes and elements and comments -->
589       <xsl:copy-of select="$merge.element/@*[not(local-name(.) = 'resourceref')]"/>
590
591       <!-- And copy any resource info attributes not in merge-->
592       <xsl:for-each select="$ref.info/@*">
593         <xsl:variable name="resource.att" select="local-name(.)"/>
594         <xsl:choose>
595           <xsl:when test="$merge.element/@*[local-name(.) = $resource.att]">
596             <!-- do nothing because overridden -->
597           </xsl:when>
598           <xsl:otherwise>
599             <!-- copy through if not overridden -->
600             <xsl:copy-of select="."/>
601           </xsl:otherwise>
602         </xsl:choose>
603       </xsl:for-each>
604
605       <!-- Copy through the merge children as they have highest priority -->
606       <xsl:copy-of select="$merge.element/node()"/>
607
608       <!-- and copy through those merge resource elements not in merge element -->
609       <xsl:for-each select="$merge.ref.info/node()">
610         <xsl:variable name="resource.node" select="local-name(.)"/>
611         <xsl:choose>
612           <xsl:when test="$merge.element/node()[local-name(.) = $resource.node]">
613             <!-- do nothing because overridden -->
614           </xsl:when>
615           <xsl:otherwise>
616             <!-- copy through -->
617             <xsl:copy-of select="."/>
618           </xsl:otherwise>
619         </xsl:choose>
620       </xsl:for-each>
621
622       <!-- And copy any module's resource info node not in merge or merge.ref -->
623       <xsl:for-each select="$ref.info/node() | 
624                             $ref.title[$omittitles.boolean = 0] |
625                             $ref.subtitle[$omittitles.boolean = 0] |
626                             $ref.titleabbrev[$omittitles.boolean = 0] |
627                             $ref.info.title[$omittitles.boolean = 0] |
628                             $ref.info.subtitle[$omittitles.boolean = 0] |
629                             $ref.info.titleabbrev[$omittitles.boolean = 0]">
630         <xsl:variable name="resource.node" select="local-name(.)"/>
631         <xsl:choose>
632           <xsl:when test="$merge.element/node()[local-name(.) = $resource.node]">
633             <!-- do nothing because overridden -->
634           </xsl:when>
635           <xsl:when test="$merge.ref.info/node()[local-name(.) = $resource.node]">
636             <!-- do nothing because overridden -->
637           </xsl:when>
638           <xsl:otherwise>
639             <!-- copy through -->
640             <xsl:copy-of select="."/>
641           </xsl:otherwise>
642         </xsl:choose>
643       </xsl:for-each>
644
645     </info>
646   </xsl:if>
647 </xsl:template>
648
649 <xsl:template match="d:relationships">
650   <xsl:message>
651     <xsl:text>WARNING: the &lt;relationships&gt; element is not currently </xsl:text>
652     <xsl:text>supported by this stylesheet.</xsl:text>
653   </xsl:message>
654 </xsl:template>
655
656 <xsl:template match="d:transforms">
657   <xsl:message>
658     <xsl:text>WARNING: the &lt;transforms&gt; element is not currently </xsl:text>
659     <xsl:text>supported by this stylesheet.</xsl:text>
660   </xsl:message>
661 </xsl:template>
662
663 <xsl:template match="d:filterin">
664   <xsl:message>
665     <xsl:text>WARNING: the &lt;filterin&gt; element is not currently </xsl:text>
666     <xsl:text>supported by this stylesheet.</xsl:text>
667   </xsl:message>
668 </xsl:template>
669
670 <xsl:template match="d:filterout">
671   <xsl:message>
672     <xsl:text>WARNING: the &lt;filterin&gt; element is not currently </xsl:text>
673     <xsl:text>supported by this stylesheet.</xsl:text>
674   </xsl:message>
675 </xsl:template>
676
677 </xsl:stylesheet>