Statistics
| Revision:

root / tmp / org.txm.core / res / org / txm / xml / xsl / tei / nlm / tei_to_nlm.xsl @ 187

History | View | Annotate | Download (29.5 kB)

1
<?xml version="1.0"?>
2
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exist="http://exist.sourceforge.net/NS/exist" xmlns="" xpath-default-namespace="http://www.tei-c.org/ns/1.0" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="#all">
3

    
4
  <!--
5
        Written by Martin Holmes, University of Victoria Humanities Computing and 
6
    Media Centre, beginning in 2008.
7
    
8
    This file is released under the Mozilla Public Licence version 1.1 (MPL 1.1).
9
    
10
    This transformation is designed to convert the limited subset of TEI elements
11
    used in the teiJournal project into an NLM file. NLM is:
12
    
13
    The National Center for Biotechnology Information (NCBI) of the National Library of
14
    Medicine (NLM) created the Journal Archiving and Interchange Tag Suite.
15
    
16
    Our target is actually the NLM Journal Publishing Tag Set, described here:
17
    
18
    http://dtd.nlm.nih.gov/publishing/tag-library/3.0/index.html
19
    
20
    The reason for creating NLM conversion is that Open Journal Systems has committed 
21
    to supporting NLM, so this provides a method of migrating data from teiJournal 
22
    to OJS.
23
    
24
    -->
25
  <xsl:output method="xml" doctype-public="-//NLM//DTD Journal Publishing DTD v3.0 20080202//EN" doctype-system="http://dtd.nlm.nih.gov/publishing/3.0/journalpublishing3.dtd" xpath-default-namespace="" indent="yes"></xsl:output>
26

    
27
  <xsl:template match="/">
28
    <article dtd-version="3.0" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
29
      <xsl:if test="TEI/@xml:lang">
30
        <xsl:copy-of select="TEI/@xml:lang"></xsl:copy-of>
31
      </xsl:if>
32
<!-- We have an ontology of TEI contribution types; this does not match 
33
     NLM at all. In NLM 3.0, the list of article-type values is suggested but 
34
     not fixed, so we can use those which are appropriate, and use our own 
35
     where there's no match. In 2.3, the list is fixed, so we'd have to convert 
36
     all our non-matching ones to "other". -->
37
        <xsl:choose>
38
          <xsl:when test="TEI/@rend='article'">
39
  <xsl:attribute name="article-type">research-article</xsl:attribute>
40
</xsl:when>
41
<xsl:when test="TEI/@rend='review_article'">
42
  <xsl:attribute name="article-type">review-article</xsl:attribute>
43
</xsl:when>
44
<xsl:when test="TEI/@rend='fiction'">
45
  <xsl:attribute name="article-type">fiction</xsl:attribute>
46
</xsl:when>
47
<xsl:when test="TEI/@rend='poetry'">
48
  <xsl:attribute name="article-type">poetry</xsl:attribute>
49
</xsl:when>
50
<xsl:when test="TEI/@rend='review'">
51
  <xsl:attribute name="article-type">book-review</xsl:attribute>
52
</xsl:when>
53
<xsl:when test="TEI/@rend='books_received'">
54
  <xsl:attribute name="article-type">books-received</xsl:attribute>
55
</xsl:when>
56
<xsl:when test="TEI/@rend='note'">
57
  <xsl:attribute name="article-type">brief-report</xsl:attribute>
58
</xsl:when>
59
<xsl:when test="TEI/@rend='discussion'">
60
  <xsl:attribute name="article-type">discussion</xsl:attribute>
61
</xsl:when>
62
<xsl:when test="TEI/@rend='editorial'">
63
  <xsl:attribute name="article-type">editorial</xsl:attribute>
64
</xsl:when>
65
<xsl:when test="TEI/@rend='preface'">
66
  <xsl:attribute name="article-type">editorial</xsl:attribute>
67
</xsl:when>
68
<xsl:when test="TEI/@rend='column'">
69
  <xsl:attribute name="article-type">discussion</xsl:attribute>
70
</xsl:when>
71
<xsl:when test="TEI/@rend='afterword'">
72
  <xsl:attribute name="article-type">editorial</xsl:attribute>
73
</xsl:when>
74
<xsl:when test="TEI/@rend='announcement'">
75
  <xsl:attribute name="article-type">announcement</xsl:attribute>
76
</xsl:when>
77
<xsl:when test="TEI/@rend='corrigendum'">
78
  <xsl:attribute name="article-type">correction</xsl:attribute>
79
</xsl:when>
80
<xsl:when test="TEI/@rend='advertisement'">
81
  <xsl:attribute name="article-type">announcement</xsl:attribute>
82
</xsl:when>
83
<xsl:when test="TEI/@rend='doc_list'">
84
  <xsl:attribute name="article-type">collection</xsl:attribute>
85
</xsl:when>
86
<xsl:when test="TEI/@rend='site_page'">
87
  <xsl:attribute name="article-type">editorial</xsl:attribute>
88
</xsl:when>
89
<xsl:when test="TEI/@rend='obituary'">
90
  <xsl:attribute name="article-type">obituary</xsl:attribute>
91
</xsl:when>
92
          <xsl:otherwise><xsl:attribute name="article-type">other</xsl:attribute></xsl:otherwise>
93
        </xsl:choose>
94
        
95
      
96
      <!--      This is the metadata block, essentially. -->
97
      <xsl:element name="front">
98

    
99
        <!-- Here we dig through the teiHeader to extract what we need to create journal metadata
100
     and article metadata. First, journal metadata: -->
101
        <xsl:element name="journal-meta">
102
          <journal-id journal-id-type="publisher">
103
          <xsl:choose>
104
          <xsl:when test="TEI/teiHeader[1]/fileDesc[1]/publicationStmt[1]/publisher[1]/choice[1]/abbr[1]">
105
            
106
              <xsl:value-of select="TEI/teiHeader[1]/fileDesc[1]/publicationStmt[1]/publisher[1]/choice[1]/abbr[1]"></xsl:value-of>
107
            
108
          </xsl:when>
109
            <xsl:otherwise>
110
              <xsl:value-of select="TEI/teiHeader[1]/fileDesc[1]/publicationStmt[1]/publisher[1]"></xsl:value-of>
111
            </xsl:otherwise>
112
          </xsl:choose>
113
            </journal-id>
114
          <issn>
115
            <xsl:value-of select="TEI/teiHeader[1]/fileDesc[1]/seriesStmt[1]/idno[@type='issn']"></xsl:value-of>
116
          </issn>
117
          <publisher>
118
            <publisher-name>
119
              <xsl:choose>
120
                <xsl:when test="TEI/teiHeader[1]/fileDesc[1]/publicationStmt[1]/publisher[1]/choice/abbr">
121
                  <xsl:value-of select="TEI/teiHeader[1]/fileDesc[1]/publicationStmt[1]/publisher[1]/choice/abbr"></xsl:value-of>
122
                  <xsl:text> (</xsl:text>
123
                  <xsl:apply-templates select="TEI/teiHeader[1]/fileDesc[1]/publicationStmt[1]/publisher[1]/choice/expan"></xsl:apply-templates>
124
                  <xsl:text>)</xsl:text>
125
                </xsl:when>
126
                <xsl:otherwise>
127
                  <xsl:value-of select="TEI/teiHeader[1]/fileDesc[1]/publicationStmt[1]/publisher[1]"></xsl:value-of>
128
                </xsl:otherwise>
129
              </xsl:choose>
130
            </publisher-name>
131
          </publisher>
132

    
133
        </xsl:element>
134

    
135
        <!--        Next, article metadata. -->
136
        <xsl:element name="article-meta">
137
          <article-id pub-id-type="other">
138
            <xsl:value-of select="TEI/@xml:id"></xsl:value-of>
139
          </article-id>
140
          <article-categories>
141
            <subj-group>
142
              <subject><xsl:value-of select="TEI/@rend" /></subject>
143
            </subj-group>
144
          </article-categories>
145
          
146
          <title-group>
147
            <article-title><xsl:apply-templates select="TEI/teiHeader[1]/fileDesc[1]/titleStmt[1]/title[@type='main']" /></article-title>
148
            <subtitle><xsl:apply-templates select="TEI/teiHeader[1]/fileDesc[1]/titleStmt[1]/title[@type='sub']" /></subtitle>
149
            <alt-title alt-title-type="runningRecto"><xsl:apply-templates select="TEI/teiHeader[1]/fileDesc[1]/titleStmt[1]/title[@type='runningRecto']" /></alt-title>
150
            <alt-title alt-title-type="runningVerso"><xsl:apply-templates select="TEI/teiHeader[1]/fileDesc[1]/titleStmt[1]/title[@type='runningVerso']" /></alt-title>
151
          </title-group>
152
          
153
          <contrib-group>
154
            <xsl:for-each select="TEI/teiHeader[1]/fileDesc[1]/titleStmt[1]/author">
155
              <contrib contrib-type="author">
156
                <xsl:apply-templates select="name"></xsl:apply-templates>
157
                <aff><xsl:apply-templates select="name/affiliation" /></aff>
158
              </contrib>
159
            </xsl:for-each>
160
          </contrib-group>
161
          
162
          <xsl:for-each select="TEI/teiHeader[1]/fileDesc[1]/seriesStmt[1]/respStmt">
163
            <contrib-group>
164
              <xsl:for-each select="name">
165
                <contrib>
166
                  <xsl:attribute name="contrib-type" select="../resp"></xsl:attribute>
167
                  <xsl:apply-templates select="." />
168
                </contrib>
169
              </xsl:for-each>
170
            </contrib-group>
171
          </xsl:for-each>
172

    
173
          <xsl:call-template name="dateToDMYTags"><xsl:with-param name="inDate" select="TEI/teiHeader[1]/fileDesc[1]/publicationStmt[1]/date[1]/@when" /><xsl:with-param name="outTagName">pub-date</xsl:with-param></xsl:call-template>
174
          
175
          <volume><xsl:apply-templates select="TEI/teiHeader[1]/fileDesc[1]/seriesStmt[1]/idno[@type='vol']" /></volume>
176
          
177
          <issue><xsl:apply-templates select="TEI/teiHeader[1]/fileDesc[1]/seriesStmt[1]/idno[@type='issue']" /></issue>
178
          
179
          <elocation-id><xsl:value-of select="TEI/teiHeader[1]/fileDesc[1]/publicationStmt[1]/idno[@type='itemNo']/@n" /></elocation-id>
180

    
181
<!-- If there is an abstract, copy it in here for the sake of completeness. -->
182
          <xsl:if test="TEI/text/body/div[@type='abstract']">
183
            <abstract>
184
              <xsl:apply-templates select="TEI/text/body/div[@type='abstract']/*" />
185
            </abstract>
186
          </xsl:if>
187

    
188
<!--        Right now, profilDesc only contains keywords, but other templates 
189
            might be added later. -->
190
        <xsl:apply-templates select="TEI/teiHeader/profileDesc"></xsl:apply-templates>
191

    
192

    
193

    
194
        </xsl:element>
195

    
196
      </xsl:element>
197

    
198
      <!--Here's the meat of the document. -->
199
      <xsl:element name="body">
200

    
201
        <xsl:apply-templates select="TEI/text/body"></xsl:apply-templates>
202

    
203
      </xsl:element>
204

    
205
      <!--      This will contain the appendices, reference list, etc. -->
206

    
207
      <xsl:element name="back">
208
<!-- Appendices first. -->
209
        <xsl:if test="TEI/text/back/div[@type='appendix']">
210
          <xsl:element name="app-group">
211
            <xsl:for-each select="TEI/text/back/div[@type='appendix']">
212
              <xsl:element name="app">
213
                <xsl:if test="@xml:id">
214
                  <xsl:attribute name="id" select="@xml:id" />
215
                </xsl:if>
216
                <xsl:apply-templates select="./*" />
217
              </xsl:element>
218
            </xsl:for-each>
219
          </xsl:element>
220
        </xsl:if>
221
        
222
<!-- Reference list        -->
223
        <xsl:if test="TEI/text/back/div[@type='bibliogr']">
224
          <xsl:variable name="bibl" select="TEI/text/back/div[@type='bibliogr']"></xsl:variable>
225
          <xsl:element name="ref-list">
226
<!-- If there's no title tag, we have to add an empty one. -->
227
            <title><xsl:value-of select="$bibl/head" /></title>
228
<!-- Now process each of the reference items. -->
229
            <xsl:for-each select="$bibl/listBibl/biblStruct">
230
              <xsl:apply-templates select="." />
231
            </xsl:for-each>
232
          </xsl:element>
233
        </xsl:if>
234
      </xsl:element>
235
    </article>
236

    
237
  </xsl:template>
238
  
239
<!-- Handling of items in profileDesc. -->
240
  <xsl:template match="profileDesc"><xsl:apply-templates /></xsl:template>
241
  <xsl:template match="textClass"><xsl:apply-templates /></xsl:template>
242
  <xsl:template match="keywords">
243
    <xsl:element name="kwd-group">
244
      <xsl:if test="@scheme">
245
        <xsl:attribute name="kwd-group-type" select="@scheme" />
246
      </xsl:if>
247
      <xsl:for-each select="list/item">
248
        <xsl:element name="kwd">
249
          <xsl:value-of select="." />
250
        </xsl:element>
251
      </xsl:for-each>
252
    </xsl:element>
253
  </xsl:template>
254
  
255
  <xsl:template name="dateToDMYTags">
256
    <xsl:param name="inDate" />
257
    <xsl:param name="outTagName" />
258
    <xsl:element name="{$outTagName}">
259
      <xsl:variable name="frags" select="tokenize($inDate, '-')" />
260
      <xsl:if test="count($frags) gt 2">
261
        <day><xsl:value-of select="$frags[3]" /></day>
262
      </xsl:if>
263
      <xsl:if test="count($frags) gt 1">
264
        <month><xsl:value-of select="$frags[2]" /></month>
265
      </xsl:if>
266
      <xsl:if test="count($frags) gt 0">
267
        <year><xsl:value-of select="$frags[1]" /></year>
268
      </xsl:if>
269
    </xsl:element>
270
  </xsl:template>
271
  
272
<!-- Block-level templates. -->
273
<!--  Document divisions/sections. -->
274
  <xsl:template match="div">
275
    <xsl:element name="sec">
276
<!-- If there's no title tag, we have to add an empty one. -->
277
      <xsl:if test="not(child::head)"><title></title></xsl:if>
278
      <xsl:apply-templates />
279
    </xsl:element>
280
  </xsl:template>
281
  
282
  <xsl:template match="div/head">
283
    <xsl:element name="title">
284
      <xsl:apply-templates />
285
    </xsl:element>
286
  </xsl:template>
287
  
288
  <xsl:template match="p | ab">
289
    <xsl:element name="p">
290
      <xsl:apply-templates />
291
    </xsl:element>
292
  </xsl:template>
293
  
294
  <xsl:template match="list">
295
    <xsl:element name="list">
296
      <xsl:if test="@type">
297
        <xsl:attribute name="list-type" select="@type" />
298
      </xsl:if>
299
      <xsl:apply-templates />
300
    </xsl:element>
301
  </xsl:template>
302
  
303
  <xsl:template match="list/item">
304
    <xsl:element name="list-item">
305
      <p>
306
        <xsl:apply-templates />
307
      </p>
308
    </xsl:element>
309
  </xsl:template>
310
  
311
    <!-- Tables are simple for the moment, but they'll get complicated. -->
312
    <xsl:template match="table">
313
      <xsl:element name="table-wrap">
314
        <xsl:if test="@rend">
315
          <xsl:attribute name="specific-use" select="@rend"/>
316
        </xsl:if>
317
        <xsl:if test="head">
318
          <xsl:element name="caption">
319
            <xsl:element name="p">
320
              <xsl:apply-templates select="head"/>
321
            </xsl:element>
322
          </xsl:element>
323
          </xsl:if>
324
        <xsl:element name="table">
325
          <xsl:if test="@xml:id"><xsl:attribute name="id" select="@xml:id" /></xsl:if>
326
            <xsl:apply-templates/>
327
        </xsl:element>
328
      </xsl:element>
329
    </xsl:template>
330
    <xsl:template match="table/row">
331
        <xsl:element name="tr">
332
            <xsl:apply-templates/>
333
        </xsl:element>
334
    </xsl:template>
335
    <xsl:template match="table/row/cell">
336
      <xsl:choose>
337
        <xsl:when test="parent::row/@role='label'">
338
          <xsl:element name="th">
339
            <xsl:apply-templates />
340
          </xsl:element>
341
        </xsl:when>
342
        <xsl:otherwise>
343
          <xsl:element name="td">
344
            <xsl:apply-templates />
345
          </xsl:element>
346
        </xsl:otherwise>
347
      </xsl:choose>
348
    </xsl:template>
349
  
350
<!-- Suppress handling of the table caption (head), because the NLM model moves it 
351
     into the parent table-wrap element, so we have to handle it at that point
352
     (above). -->
353
  <xsl:template match="table/head"></xsl:template>
354
  
355
<!--  Low-level element templates. -->
356
  
357
<!-- Copy xml:id to id attribute in output. -->
358
  <xsl:template match="@xml:id"><xsl:attribute name="id" select="." /></xsl:template>
359
  
360
<!-- Copy xml:lang to output. -->
361
  <xsl:template match="@xml:lang"><xsl:copy-of select="." /></xsl:template>
362
  
363
<!-- Quotations. Our TEI model is more sophisticated that NLM here; we need 
364
to simplify a bit. -->
365
  <xsl:template match="cit">
366
    <xsl:if test="quote">
367
      <xsl:element name="disp-quote">
368
        <xsl:if test="@rend">
369
          <xsl:attribute name="specific-use" select="@rend" />
370
        </xsl:if>
371
<!-- If the quote is already divided into paragraphs, we can simply process
372
     it; if not, we must supply a p tag, because NLM requires a block tag 
373
     inside disp-quote. -->
374
        <xsl:choose>
375
          <xsl:when test="quote/p">
376
            <xsl:apply-templates select="quote" />
377
          </xsl:when>
378
          <xsl:otherwise>
379
            <xsl:element name="p">
380
              <xsl:apply-templates select="quote" />
381
            </xsl:element>
382
          </xsl:otherwise>
383
        </xsl:choose>
384
        <xsl:if test="@rend='block' and ref">
385
          <xsl:element name="attrib">
386
            <xsl:apply-templates select="ref" />
387
          </xsl:element>
388
        </xsl:if>
389
      </xsl:element>
390
    </xsl:if>
391
    <xsl:if test="not(@rend='block') and ref">
392
       <xsl:apply-templates select="ref" />
393
    </xsl:if>
394
  </xsl:template>
395
  
396
  <xsl:template match="ref">
397
<!-- For ref elements, we need to distinguish between internal and external 
398
because NLM handles them differently. -->
399
    <xsl:choose>
400
<!-- Internal reference. -->
401
      <xsl:when test="starts-with(@target, '#')">
402
        <xsl:element name="xref">
403
          <xsl:variable name="targId" select="substring-after(@target, '#')" />
404
          <xsl:attribute name="rid" select="$targId" />
405
<!-- If it's a reference to a biblStruct element in the back matter, then it should 
406
be given the recommended @ref-type. -->
407
          <xsl:if test="//back//biblStruct[@xml:id = $targId]"><xsl:attribute name="ref-type">bibr</xsl:attribute></xsl:if>
408
          
409
<!-- We have to be careful of embedded tags, because xref has a very 
410
     impoverished content model. -->
411
          <xsl:apply-templates />
412
        </xsl:element>
413
      </xsl:when>
414
<!-- External reference. -->
415
      <xsl:otherwise>
416
        <xsl:element name="ext-link">
417
          <xsl:attribute name="xlink:href" select="@target" />
418
<!-- We have to be careful of embedded tags, because ext-link has a very 
419
     impoverished content model. -->
420
          <xsl:apply-templates />
421
        </xsl:element>
422
      </xsl:otherwise>
423
    </xsl:choose>
424
  </xsl:template>
425
  
426
<!-- Abbreviations.  -->
427
  <xsl:template match="choice[abbr]">
428
    <xsl:apply-templates select="abbr"></xsl:apply-templates>
429
  </xsl:template>
430
  
431
  <xsl:template match="abbr">
432
    <xsl:choose>
433
      <xsl:when test="not(ancestor::ref)">
434
        <xsl:element name="abbrev">
435
        <xsl:apply-templates />
436
        <xsl:if test="preceding-sibling::expan"><def><p><xsl:apply-templates select="preceding-sibling::expan[1]" /></p></def></xsl:if>
437
        <xsl:if test="following-sibling::expan"><def><p><xsl:apply-templates select="following-sibling::expan[1]" /></p></def></xsl:if>
438
        </xsl:element>
439
      </xsl:when>
440
      <xsl:otherwise>
441
        <xsl:value-of select="." />
442
      </xsl:otherwise>
443
    </xsl:choose>
444
    
445
  </xsl:template>
446
  
447
  
448
<!-- Name elements are complicated, because we distinguish them by type, 
449
     but NLM makes a distinction between the names of people and other 
450
     types of name. The only appropriate NLM element I can find for the latter
451
     is named-content. 
452
     There is a further annoying complication, in that the <name> element 
453
     in NLM can't show up inside regular body text, apparently.      
454
-->
455

    
456
  <xsl:template match="name[@type='person' or not(@type)][not(ancestor::div)]">
457
    <xsl:element name="name">
458
      <surname><xsl:apply-templates select="surname" /></surname>
459
      <given-names><xsl:apply-templates select="forename" /></given-names>
460
    </xsl:element>
461
  </xsl:template>
462
  
463
  <xsl:template match="name[@type='person' or not(@type)][ancestor::div]">
464
    <xsl:element name="named-content">
465
      <xsl:attribute name="content-type">person</xsl:attribute>
466
      <xsl:value-of select="." />
467
    </xsl:element>
468
  </xsl:template>
469
  
470
  <xsl:template match="affiliation/name[@type='org']">
471
    <xsl:element name="institution">
472
      <xsl:value-of select="." />
473
    </xsl:element>
474
  </xsl:template>
475
  
476
  <xsl:template match="name[@type and not(@type='person')][ancestor::div]">
477
    <xsl:element name="named-content">
478
      <xsl:attribute name="content-type" select="@type" />
479
      <xsl:apply-templates />
480
    </xsl:element>
481
  </xsl:template>
482
  
483
<!-- Notes (footnotes/endnotes). -->
484
  <xsl:template match="note">
485
    <xsl:element name="fn">
486
      <xsl:choose>
487
        <xsl:when test="not(child::p)">
488
          <xsl:element name="p">
489
            <xsl:apply-templates />
490
          </xsl:element>
491
        </xsl:when>
492
        <xsl:otherwise>
493
          <xsl:apply-templates />
494
        </xsl:otherwise>
495
      </xsl:choose>
496
    </xsl:element>
497
  </xsl:template>
498
  
499
<!-- Figures and graphics. -->
500
  <xsl:template match="figure">
501
    <xsl:element name="fig">
502
      <xsl:if test="@xml:id">
503
        <xsl:attribute name="id" select="@xml:id" />
504
      </xsl:if>
505
      <xsl:apply-templates />
506
    </xsl:element>  
507
  </xsl:template>
508
  
509
  <xsl:template match="figure/head">
510
    <caption><title><xsl:apply-templates /></title></caption>
511
  </xsl:template>
512
  
513
  <xsl:template match="graphic">
514
    <xsl:element name="graphic">
515
      <xsl:attribute name="xlink:href" select="@url" />
516
    </xsl:element>
517
  </xsl:template>
518
  
519
<!-- Verse lines and groups. -->
520
  <xsl:template match="lg">
521
    <xsl:element name="verse-group">
522
      <xsl:apply-templates />
523
    </xsl:element>
524
  </xsl:template>
525
  
526
  <xsl:template match="l">
527
    <xsl:element name="verse-line">
528
      <xsl:apply-templates />
529
    </xsl:element>
530
  </xsl:template>
531
  
532
  
533
<!-- Bibliographical items. -->
534
  <xsl:template match="listBibl/biblStruct">
535
    <ref id="{@xml:id}">
536
<!-- Now the hard bit. NLM's model is radically different from TEI's. -->
537
      <element-citation publication-type="{@type}">
538
        
539
<!-- We're going to take the approach of picking out the information we 
540
     need from where we expect to find it, rather than trying to apply 
541
     templates in some generic way, because the structured nature of 
542
     TEI biblStructs is so different from the rather looser structure 
543
     of NLM. -->
544
        
545
<!-- First we look for authors. These might be in the analytic or in the 
546
monogr; try analytic first. -->
547
        <xsl:if test="analytic">
548
<!-- In this case, we should be able to get both title and authors from here. -->
549
          <person-group person-group-type="author">
550
            <xsl:for-each select="analytic/author/name">
551
              <name>
552
                <surname><xsl:apply-templates select="surname" /></surname>
553
                <given-names><xsl:apply-templates select="forename" /></given-names>
554
              </name>
555
            </xsl:for-each>
556
          </person-group>
557
<!-- Now we can get the title from here. NLM has an article-title element, which 
558
     will do for journal articles; it uses chapter-title for book chapters. -->
559
          <xsl:choose>
560
            <xsl:when test="@type='book'"><chapter-title><xsl:apply-templates select="analytic/title" /></chapter-title></xsl:when>
561
            <xsl:otherwise><article-title><xsl:apply-templates select="analytic/title" /></article-title></xsl:otherwise>
562
          </xsl:choose> 
563
        </xsl:if>
564
<!-- Now we look for additional information in the monogr element. -->
565
        <xsl:if test="monogr">
566
<!-- If there's a monogr title element, it could be the level m or j (books and 
567
journals), or it could be s (series title). We need to handle each separately.-->
568
          <xsl:for-each select="monogr/title[@level='m' or @level='u' or @level='j']">
569
            <source><xsl:value-of select="." /></source>
570
          </xsl:for-each>
571
<!-- Series titles. -->
572
          <xsl:for-each select="monogr/title[@level='s']">
573
            <series><xsl:value-of select="." /></series>
574
          </xsl:for-each>
575
<!-- Now we should look for authors and editors at the monogr level. -->
576
          <xsl:if test="monogr/author">
577
            <person-group person-group-type="author">
578
              <xsl:for-each select="monogr/author/name">
579
                <name>
580
                  <surname><xsl:apply-templates select="surname" /></surname>
581
                  <given-names><xsl:apply-templates select="forename" /></given-names>
582
                </name>
583
              </xsl:for-each>
584
            </person-group>
585
          </xsl:if>
586
          <xsl:if test="monogr/editor">
587
            <person-group person-group-type="editor">
588
              <xsl:for-each select="monogr/editor/name">
589
                <name>
590
                  <surname><xsl:apply-templates select="surname" /></surname>
591
                  <given-names><xsl:apply-templates select="forename" /></given-names>
592
                </name>
593
              </xsl:for-each>
594
            </person-group>
595
            <xsl:if test="edition">
596
              <edition><xsl:value-of select="edition" /></edition>  
597
            </xsl:if>
598
          </xsl:if>
599
          
600
<!-- In TEI, idno elements are used for a variety of tasks. -->
601
          <xsl:for-each select="monogr/idno">
602
            <xsl:choose>
603
              <xsl:when test="@type='ISSN'">
604
                <issn><xsl:value-of select="." /></issn>
605
              </xsl:when>
606
              <xsl:when test="@type='ISBN'">
607
                <isbn><xsl:value-of select="." /></isbn>
608
              </xsl:when>
609
            </xsl:choose>
610
          </xsl:for-each>
611
          
612
<!-- Now we get the publication information from the imprint element. This can 
613
     be handled with more conventional one-to-one mapping, so templates will do.-->
614
          <xsl:apply-templates select="monogr/imprint" />
615
        </xsl:if>
616
<!-- We should process any respStmt elements in analytic or monogr. -->
617
          <xsl:apply-templates select="descendant::respStmt">
618
          </xsl:apply-templates>
619
      </element-citation>
620
    </ref>
621
  </xsl:template>
622
  
623
<!-- These are mini-templates for the content of the imprint element in a 
624
biblStruct. -->
625
  <xsl:template match="biblStruct/monogr/imprint">
626
    <xsl:apply-templates />
627
  </xsl:template>
628
  
629
  <xsl:template match="publisher">
630
    <publisher-name><xsl:apply-templates /></publisher-name>
631
  </xsl:template>
632
  
633
  <xsl:template match="pubPlace">
634
    <publisher-loc><xsl:apply-templates /></publisher-loc>
635
  </xsl:template>
636
  
637
  <xsl:template match="biblStruct/monogr/imprint/date">
638
    <year><xsl:value-of select="substring(@when, 1, 4)" /></year>
639
    <xsl:if test="string-length(@when) gt 6">
640
      <month><xsl:value-of select="substring(@when, 6, 2)" /></month>
641
      <xsl:if test="string-length(@when) gt 9">
642
        <day><xsl:value-of select="substring(@when, 9, 2)" /></day>
643
      </xsl:if>
644
    </xsl:if>
645
  </xsl:template>
646
  
647
  <xsl:template match="biblStruct/monogr/imprint/biblScope">
648
    <xsl:choose>
649
      <xsl:when test="@type='vol'">
650
        <volume><xsl:value-of select="." /></volume>
651
      </xsl:when>
652
      <xsl:when test="@type='issue'">
653
        <issue><xsl:value-of select="." /></issue>
654
      </xsl:when>
655
      <xsl:when test="@type='pp'">
656
        <fpage><xsl:value-of select="substring-before(., '-')"/></fpage>
657
        <lpage><xsl:value-of select="substring-after(., '-')"/></lpage>
658
      </xsl:when>
659
<!--       ANY MORE??? -->
660
      <!--<xsl:when test="@type=''"></xsl:when>
661
      <xsl:when test="@type=''"></xsl:when>
662
      <xsl:when test="@type=''"></xsl:when>-->
663
      <xsl:otherwise><comment><xsl:value-of select="." /></comment></xsl:otherwise>
664
    </xsl:choose>
665
  </xsl:template>
666
  
667
  <xsl:template match="biblStruct//note">
668
    <comment><xsl:value-of select="." /></comment>
669
  </xsl:template>
670
  
671
  <xsl:template match="respStmt[ancestor::biblStruct]">
672
    <person-group person-group-type="{resp}">
673
      <xsl:for-each select="name">
674
        <name>
675
                  <surname><xsl:apply-templates select="surname" /></surname>
676
                  <given-names><xsl:apply-templates select="forename" /></given-names>
677
                </name>
678
      </xsl:for-each>
679
    </person-group>
680
  </xsl:template>
681
  
682
<!-- The soCalled element has no analogue in NLM; the best we can do 
683
is probably to use style-content, enabling us to include the quotes and
684
at the same time explain them. -->
685
  <xsl:template match="soCalled">
686
    <styled-content style-type="scare quotes" style="::before: content(open-quote); ::after: content(close-quote);">
687
      <xsl:apply-templates />
688
    </styled-content>
689
  </xsl:template>
690
  
691
<!-- The mentioned tag is similarly difficult, as is the tag element, and term. -->
692
  <xsl:template match="mentioned">
693
    <styled-content style-type="mentioned" style="font-style: italic;">
694
      <xsl:apply-templates />
695
    </styled-content>
696
  </xsl:template>
697

    
698
  <xsl:template match="tag">
699
    <styled-content style-type="XML tag" style="::before: content(&lt;); ::after: content(&gt;); font-family: monospace;">
700
      <xsl:apply-templates />
701
    </styled-content>
702
  </xsl:template>
703
  
704
  <xsl:template match="term">
705
    <styled-content style-type="term" style="font-style: italic;">
706
      <xsl:apply-templates />
707
    </styled-content>
708
  </xsl:template>
709
  
710
<!-- Line breaks are equivalent to <break/>, but cannot appear in paragraphs 
711
     What nonsense. -->
712
  <xsl:template match="lb"><xsl:comment>There should be a line-break here.</xsl:comment></xsl:template>
713
  
714
<!-- Inline elements. -->
715
<!-- There's no standard way to do document titles in the body text in NLM. -->
716
  <xsl:template match="title[not(ancestor::biblStruct) and not(ancestor::teiHeader)]">
717
    <named-content content-type="title_level_{@level}">
718
<!-- That takes care of identifying the title type. Now we might as well 
719
have a shot at styling it. -->
720
      <xsl:choose>
721
        <xsl:when test="@level='m' or @level='j'">
722
          <italic><xsl:apply-templates /></italic>
723
        </xsl:when>
724
        <xsl:when test="@level='a'">
725
          &quot;<xsl:apply-templates />&quot;
726
        </xsl:when>
727
      </xsl:choose>
728
    </named-content>  
729
  </xsl:template>
730
  
731
<!--  Text style markup. -->
732
<!--  Bold. -->
733
  <xsl:template match="hi[@rend='bold']">
734
    <xsl:element name="bold"><xsl:apply-templates /></xsl:element>
735
  </xsl:template>
736
<!--  Italics. -->
737
  <xsl:template match="hi[@rend='italic']">
738
    <xsl:element name="italic"><xsl:apply-templates /></xsl:element>
739
  </xsl:template> 
740
<!--  Underline. -->
741
  <xsl:template match="hi[@rend='underline']">
742
    <xsl:element name="underline"><xsl:apply-templates /></xsl:element>
743
  </xsl:template>
744
<!--  Overline. -->
745
  <xsl:template match="hi[@rend='overline']">
746
    <xsl:element name="overline"><xsl:apply-templates /></xsl:element>
747
  </xsl:template>
748

    
749
</xsl:stylesheet>