Project

General

Profile

metacat / lib / oaipmh / eml201to210.xsl @ 4944

1
<?xml version="1.0"?>
2
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3
  xmlns:eml="eml://ecoinformatics.org/eml-2.1.0" version="1.0">
4
  <xsl:output method="xml" indent="yes"></xsl:output>
5
  <!--<xsl:strip-space elements="*"></xsl:strip-space>-->
6
  <xsl:param name="package-id" select="'newID'"/>
7
	
8
  <xsl:template match="/* ">
9
    <!--handle top level element-->
10
    <xsl:element name="eml:eml">   
11
      <!--<xsl:copy-of select="@*"></xsl:copy-of>-->
12
      <!--<xsl:attribute name="xsi:schemaLocation">eml://ecoinformatics.org/eml-2.1.0 eml.xsd</xsl:attribute>-->
13

    
14
	  <!--<xsl:copy-of select="namespace::*[not(starts-with(.,'eml://ecoinformatics.org/')) or . != 'http://www.w3.org/2001/XMLSchema-instance']"/>-->
15
      <xsl:for-each select="@*">
16
	   <xsl:choose>
17
	    <xsl:when test="namespace-uri()='http://www.w3.org/2001/XMLSchema-instance'">
18
        <xsl:attribute name="xsi:{local-name()}" namespace="{namespace-uri()}">
19
          <xsl:variable name="value" select="."></xsl:variable>
20
          <xsl:choose>
21
            <!--change eml200 and stmml to eml210 and stmml-1.1 in attribute-->
22
            <xsl:when test="contains($value, &quot;eml://ecoinformatics.org/eml-2.0.0&quot;)">
23
              <xsl:variable name="first-replace">
24
                 <xsl:call-template name="replace-string">
25
                    <xsl:with-param name="text" select="$value"></xsl:with-param>
26
                    <xsl:with-param name="replace" select="'eml://ecoinformatics.org/eml-2.0.0'"></xsl:with-param>
27
                    <xsl:with-param name="with" select="'eml://ecoinformatics.org/eml-2.1.0'"></xsl:with-param>
28
                 </xsl:call-template>
29
			   </xsl:variable>
30
			   <xsl:variable name="second-replace">
31
                 <xsl:call-template name="replace-string">
32
                    <xsl:with-param name="text" select="$first-replace"></xsl:with-param>
33
                    <xsl:with-param name="replace" select="'http://www.xml-cml.org/schema/stmml'"></xsl:with-param>
34
                    <xsl:with-param name="with" select="'http://www.xml-cml.org/schema/stmml-1.1'"></xsl:with-param>
35
                 </xsl:call-template>
36
			   </xsl:variable>
37
				<xsl:value-of select="$second-replace"></xsl:value-of>
38
            </xsl:when>
39
			 <!--change eml201 and stmml to eml210 and stmml-1.1 in attribute-->
40
            <xsl:when test="contains($value, 'eml://ecoinformatics.org/eml-2.0.1') or contains($value, 'http://www.xml-cml.org/schema/stmml')">
41
			  <xsl:variable name="first-replace">
42
                 <xsl:call-template name="replace-string">
43
                    <xsl:with-param name="text" select="$value"></xsl:with-param>
44
                    <xsl:with-param name="replace" select="'eml://ecoinformatics.org/eml-2.0.1'"></xsl:with-param>
45
                    <xsl:with-param name="with" select="'eml://ecoinformatics.org/eml-2.1.0'"></xsl:with-param>
46
                 </xsl:call-template>
47
			   </xsl:variable>
48
			   <xsl:variable name="second-replace">
49
                 <xsl:call-template name="replace-string">
50
                    <xsl:with-param name="text" select="$first-replace"></xsl:with-param>
51
                    <xsl:with-param name="replace" select="'http://www.xml-cml.org/schema/stmml'"></xsl:with-param>
52
                    <xsl:with-param name="with" select="'http://www.xml-cml.org/schema/stmml-1.1'"></xsl:with-param>
53
                 </xsl:call-template>
54
			   </xsl:variable>
55
				<xsl:value-of select="$second-replace"></xsl:value-of>
56
            </xsl:when>
57
            <xsl:otherwise>
58
              <xsl:value-of select="."></xsl:value-of>
59
            </xsl:otherwise>
60
          </xsl:choose>
61
        </xsl:attribute>
62
		</xsl:when>
63
		<xsl:otherwise>
64
            <xsl:choose>
65
               <xsl:when test="name()='packageId'">
66
				   <!-- handle package id: if there is no given packageid, it will use the old one. Otherwise, using the given id-->
67
			       <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
68
					    <xsl:choose>
69
							<xsl:when test="$package-id='newID'">
70
								<xsl:value-of select="."/>
71
							</xsl:when>
72
							<xsl:otherwise>
73
								<xsl:value-of select="$package-id"/>
74
							</xsl:otherwise>
75
						</xsl:choose>
76
			       </xsl:attribute>
77
               </xsl:when>
78
               <xsl:otherwise>
79
				  <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
80
                        <xsl:value-of select="."/>
81
                   </xsl:attribute> 
82
               </xsl:otherwise>
83
            </xsl:choose>
84
		</xsl:otherwise>
85
       </xsl:choose>
86
      </xsl:for-each>
87
      <!--<xsl:attribute name="xsi:schemaLocation">
88
		  <xsl:value-of select='translate(@xsi:schemaLocation, "eml-2.0.1", "eml-2.1.0")'/>
89
	  </xsl:attribute>-->
90
      <!-- move the access sub tree to top level-->
91
      <xsl:apply-templates mode="copy-top-access-tree" select="/*/dataset/access"></xsl:apply-templates>
92
      <xsl:apply-templates mode="copy-top-access-tree" select="/*/citation/access"></xsl:apply-templates>
93
      <xsl:apply-templates mode="copy-top-access-tree" select="/*/software/access"></xsl:apply-templates>
94
      <xsl:apply-templates mode="copy-top-access-tree" select="/*/protocol/access"></xsl:apply-templates>
95

    
96
      <xsl:for-each select="/*/*">
97
        <xsl:choose>
98
          <xsl:when test="name()='dataset'">
99
            <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
100
              <xsl:copy-of select="@*"></xsl:copy-of>
101
              <xsl:apply-templates mode="handle-elements-under-main-module" select="."
102
              ></xsl:apply-templates>
103
            </xsl:element>
104
          </xsl:when>
105

    
106
          <xsl:when test="name()='citation'">
107
            <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
108
              <xsl:copy-of select="@*"></xsl:copy-of>
109
              <xsl:apply-templates mode="handle-elements-under-main-module" select="."
110
              ></xsl:apply-templates>
111
            </xsl:element>
112
          </xsl:when>
113

    
114
          <xsl:when test="name()='software'">
115
            <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
116
              <xsl:copy-of select="@*"></xsl:copy-of>
117
              <xsl:apply-templates mode="handle-elements-under-main-module" select="."
118
              ></xsl:apply-templates>
119
            </xsl:element>
120
          </xsl:when>
121

    
122
          <xsl:when test="name()='protocol'">
123
            <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
124
              <xsl:copy-of select="@*"></xsl:copy-of>
125
              <xsl:apply-templates mode="handle-elements-under-main-module" select="."
126
              ></xsl:apply-templates>
127
            </xsl:element>
128
          </xsl:when>
129

    
130
          <xsl:when test="name()='additionalMetadata'">
131
            <xsl:apply-templates mode="handle-additionalMetadata" select="."></xsl:apply-templates>
132
          </xsl:when>
133

    
134
        </xsl:choose>
135
      </xsl:for-each>
136
    </xsl:element>
137
	 <xsl:message terminate="no">
138
		 <xsl:call-template name="output_message4_warn"/>
139
	  </xsl:message>
140
  </xsl:template>
141

    
142
  <!-- handle make changes under main module (dataset, citation, protocol and software) -->
143
  <xsl:template mode="handle-elements-under-main-module" match="*">
144
    <xsl:for-each select="./*">
145
      <xsl:choose>
146
        <xsl:when test="name()='access'">
147
          <xsl:apply-templates mode="do-nothing" select="."></xsl:apply-templates>
148
        </xsl:when>
149
        <xsl:otherwise>
150
          <xsl:apply-templates select="."></xsl:apply-templates>
151
        </xsl:otherwise>
152
      </xsl:choose>
153
    </xsl:for-each>
154
  </xsl:template>
155

    
156
  <!-- main template which will copy nodes recursively-->
157
  <xsl:template match="*">
158
    <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
159
      <xsl:copy-of select="@*"></xsl:copy-of>
160
      <xsl:apply-templates></xsl:apply-templates>
161
    </xsl:element>
162
  </xsl:template>
163

    
164
  <!-- fixing attributeList/attribute/measurementScale/datetime -> .../dateTime -->
165
  <xsl:template match="attributeList/attribute/measurementScale/datetime">
166
    <xsl:element name="dateTime" namespace="{namespace-uri(.)}">
167
      <xsl:copy-of select="@*"></xsl:copy-of>
168
      <xsl:apply-templates mode="copy-no-ns" select="./*"></xsl:apply-templates>
169
    </xsl:element>
170
  </xsl:template>
171

    
172
  <!-- change the name of element form method to methods -->
173
  <xsl:template match="dataTable/method | spatialRaster/method | spatialVector/method 
174
	  | view/method | storedProcedure/method | otherEntity/method">
175
    <xsl:element name="methods" namespace="{namespace-uri(.)}">
176
      <xsl:copy-of select="@*"></xsl:copy-of>
177
      <xsl:apply-templates mode="copy-no-ns-with-access-move" select="./*"></xsl:apply-templates>
178
    </xsl:element>
179
  </xsl:template>
180

    
181
  <!-- change the name of element form method to methods -->
182
  <xsl:template match="attribute/method">
183
    <xsl:element name="methods" namespace="{namespace-uri(.)}">
184
      <xsl:copy-of select="@*"></xsl:copy-of>
185
      <xsl:apply-templates mode="copy-no-ns-with-access-move" select="./*"></xsl:apply-templates>
186
    </xsl:element>
187
  </xsl:template>
188
	
189
	
190
	<!-- since under element "method", it can have distribution access movement, so this template will handle that-->
191
    <!-- copy node and children without namespace -->
192
  <xsl:template mode="copy-no-ns-with-access-move" match="*">
193
	 <xsl:choose>
194
		 <xsl:when test="name()='distribution' and name(parent::node())='implementation' and name(../..)='software'">			  
195
			 <xsl:call-template name="move-access"/>
196
		  </xsl:when>
197
		 <xsl:otherwise>
198
		      <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
199
                <xsl:copy-of select="@*"></xsl:copy-of>
200
                <xsl:apply-templates mode="copy-no-ns-with-access-move"></xsl:apply-templates>
201
              </xsl:element>
202
		 </xsl:otherwise>
203
	 </xsl:choose>   
204
  </xsl:template>
205

    
206
     <!--template to match physical/distribution and software/implementation/distribution which need to move around access module-->
207
	<xsl:template match="physical/distribution | software/implementation/distribution">
208
		<xsl:call-template name="move-access"/>
209
	</xsl:template>
210
	
211
  <!-- Move the access tree of data file level from additionalMetadata part to physical/distribution or software/implementation/distribution part.
212
           If we find the id of physical/distribution is in aditionalMetadata/describe and it 
213
             has sibling of access subtree, copy the subtree to physical/distribution -->
214
  <xsl:template name="move-access">
215
    <xsl:element name="distribution" namespace="{namespace-uri(.)}">
216
      <xsl:copy-of select="@*"></xsl:copy-of>
217
      <xsl:apply-templates mode="copy-no-ns" select="./*"></xsl:apply-templates>
218
      <!--distribution doesn't have any access node yet. Move the subtree from addtionalMetadata to distribution-->
219
      <!--find the id in addtionalMetacat/describes-->
220
      <xsl:variable name="id" select="@id"></xsl:variable>
221
      <!-- count how many additionalMetadata/access describing same distribution is -->
222
      <xsl:variable name="countAccessTree"
223
        select="count(/*/additionalMetadata[describes=$id]/access | /*/additionalMetadata[describes=$id]/metadata/access)"></xsl:variable>
224
      <xsl:choose>
225
        <xsl:when test="$countAccessTree=1">
226
          <!-- only has one access tree, we need copy it to distribution-->
227
          <xsl:apply-templates mode="copy-no-ns"
228
            select="/*/additionalMetadata[describes=$id]/access | /*/additionalMetadata[describes=$id]/metadata/access"
229
          ></xsl:apply-templates>
230
        </xsl:when>
231
        <xsl:when test="$countAccessTree &gt; 1">
232
          <!-- has more than one access tree, we need merge them-->
233
          <!--This means document have two or more addtionalMetadata
234
					          with access tree describing same distribution.
235
                       		<additionalMetadata>
236
                          		<describes>100</describe>
237
                          		<access>...</access>
238
                        	</additionalMetadata>
239
						 	<additionalMetadata>
240
                          		<describes>100</describe>
241
                          		<access>...</access>
242
                        	</additionalMetadata>-->
243
          <xsl:variable name="totalOrderNumber"
244
            select="count(/*/additionalMetadata[describes=$id]/access | /*/additionalMetadata[describes=$id]/metadata/access)"></xsl:variable>
245
          <xsl:variable name="totalAllowFirstNumber"
246
            select="count(/*/additionalMetadata[describes=$id]/access[@order='allowFirst'] | /*/additionalMetadata[describes=$id]/metadata/access[@order='allowFirst'])"></xsl:variable>
247
          <xsl:variable name="totalDenyFirstNumber"
248
            select="count(/*/additionalMetadata[describes=$id]/access[@order='denyFirst'] | /*/additionalMetadata[describes=$id]/metadata/access[@order='denyFirst'])"></xsl:variable>
249
          <xsl:choose>
250
            <xsl:when
251
              test="$totalOrderNumber=$totalAllowFirstNumber or $totalOrderNumber=$totalDenyFirstNumber">
252
              <!-- all access subtrees have same order, just merge it-->
253
              <xsl:element name="access">
254
                <xsl:copy-of
255
                  select="/*/additionalMetadata[describes=$id]/access/@* | /*/additionalMetadata[describes=$id]/metadata/access/@*"></xsl:copy-of>
256
                <xsl:for-each
257
                  select="/*/additionalMetadata[describes=$id]/access | /*/additionalMetadata[describes=$id]/metadata/access">
258
                  <xsl:apply-templates mode="copy-no-ns" select="./*"></xsl:apply-templates>
259
                </xsl:for-each>
260
              </xsl:element>
261
            </xsl:when>
262
            <xsl:otherwise>
263
              <xsl:message terminate="no">
264
                <xsl:call-template name="output_message1_warn">
265
                <xsl:with-param name="current_node" select="current()"></xsl:with-param>
266
              </xsl:call-template> </xsl:message>
267
            </xsl:otherwise>
268
          </xsl:choose>
269
        </xsl:when>
270
      </xsl:choose>
271
    </xsl:element>
272
  </xsl:template>
273

    
274

    
275
  <!-- copy access tree under dataset(or protocol, software and citation) to the top level -->
276
  <xsl:template mode="copy-top-access-tree" match="*">
277
    <xsl:apply-templates mode="copy-no-ns" select="."></xsl:apply-templates>
278
  </xsl:template>
279

    
280
  <!-- do nothing for this element (removing it)-->
281
  <xsl:template mode="do-nothing" match="*"> </xsl:template>
282

    
283
  <!-- copy node and children without namespace -->
284
  <!--<xsl:template mode="copy-no-ns" match="*">
285
    <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
286
      <xsl:copy-of select="@*"></xsl:copy-of>
287
      <xsl:apply-templates mode="copy-no-ns"></xsl:apply-templates>
288
    </xsl:element>
289
  </xsl:template>-->
290
	
291
	
292
	<!-- copy node and children without showing default namespace. 
293
		But if the namespace is stmml, the namespace will be changed to stmml-1.1 -->
294
  <xsl:template mode="copy-no-ns" match="*">
295
   <xsl:choose>
296
	  <!--handle stmml element and attribute-->
297
	 <xsl:when test="namespace-uri()='http://www.xml-cml.org/schema/stmml'">
298
        <xsl:element name="stmml:{local-name()}" namespace="http://www.xml-cml.org/schema/stmml-1.1">
299
              <xsl:for-each select="@*">
300
	              <xsl:choose>
301
	                 <xsl:when test="namespace-uri()='http://www.w3.org/2001/XMLSchema-instance'">
302
                         <xsl:attribute name="xsi:{local-name()}" namespace="http://www.w3.org/2001/XMLSchema-instance">
303
                              <xsl:variable name="value" select="."></xsl:variable>
304
                                 <xsl:choose>
305
                                      <!--change stmml to stmml-1.1 in attribute-->
306
                                         <xsl:when test="contains($value, &quot;http://www.xml-cml.org/schema/stmml&quot;)">
307
                                              <xsl:call-template name="replace-string">
308
                                                 <xsl:with-param name="text" select="$value"></xsl:with-param>
309
                                                  <xsl:with-param name="replace" select="'http://www.xml-cml.org/schema/stmml'"></xsl:with-param>
310
                                                  <xsl:with-param name="with" select="'http://www.xml-cml.org/schema/stmml-1.1'"></xsl:with-param>
311
                                              </xsl:call-template>
312
                                          </xsl:when>
313
                                          <xsl:otherwise>
314
                                            <xsl:value-of select="."></xsl:value-of>
315
                                          </xsl:otherwise>
316
                              </xsl:choose>
317
                        </xsl:attribute>
318
		           </xsl:when>
319
		           <xsl:otherwise>
320
			           <xsl:copy-of select="."></xsl:copy-of>
321
		           </xsl:otherwise>
322
               </xsl:choose>
323
           </xsl:for-each>
324
           <xsl:apply-templates mode="copy-no-ns"></xsl:apply-templates>
325
        </xsl:element>
326
	 </xsl:when>
327
	  <!--handle non-stmml element-->
328
	 <xsl:otherwise>
329
		 <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
330
            <xsl:copy-of select="@*"></xsl:copy-of>
331
            <xsl:apply-templates mode="copy-no-ns"></xsl:apply-templates>
332
         </xsl:element>
333
     </xsl:otherwise>
334
   </xsl:choose>
335
  </xsl:template>
336
	
337
	<!-- if the element has no element child and value is empty string or whitespace and element name is not recordDelimiter, physicalLineDelimiter and fieldDelimiter,
338
      the tranformation will be terminated. -->
339
  <xsl:template match="*[not(*) and ((text() and not(normalize-space(text()) != '')) or .='') 
340
       and  name(.) != 'recordDelimiter' and name(.) != 'physicalLineDelimiter' and name(.) != 'fieldDelimiter' ]">
341
      <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
342
            <xsl:copy-of select="@*"></xsl:copy-of>
343
            <xsl:value-of select="."/>
344
      </xsl:element>
345
      <xsl:message terminate="no">
346
        <xsl:call-template name="output_message3_warn">
347
          <xsl:with-param name="current_node" select="."/>
348
        </xsl:call-template>
349
      </xsl:message>
350
  </xsl:template>
351
    
352
  <xsl:template mode="copy-no-ns-with-access-move" match="*[not(*) and ((text() and not(normalize-space(text()) != '')) or .='') 
353
       and name(.) != 'recordDelimiter' and name(.) != 'physicalLineDelimiter' and name(.) != 'fieldDelimiter' ]">
354
      <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
355
            <xsl:copy-of select="@*"></xsl:copy-of>
356
            <xsl:value-of select="."/>
357
      </xsl:element>
358
      <xsl:message terminate="no">
359
        <xsl:call-template name="output_message3_warn">
360
          <xsl:with-param name="current_node" select="."/>
361
        </xsl:call-template>
362
      </xsl:message>
363
  </xsl:template>
364
    
365
  <xsl:template mode="copy-no-ns" match="*[not(*) and ((text() and not(normalize-space(text()) != '')) or .='') 
366
       and name(.) != 'recordDelimiter' and name(.) != 'physicalLineDelimiter' and name(.) != 'fieldDelimiter' ]">
367
      <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
368
            <xsl:copy-of select="@*"></xsl:copy-of>
369
            <xsl:value-of select="."/>
370
      </xsl:element>
371
      <xsl:message terminate="no">
372
        <xsl:call-template name="output_message3_warn">
373
          <xsl:with-param name="current_node" select="."/>
374
        </xsl:call-template>
375
      </xsl:message>
376
  </xsl:template>
377

    
378

    
379
  <!--Handle additionMetadata part. Here are 4 scenarios:
380
         1. <additionalMetadata>
381
					<describes>100</describes>
382
                     <foo>.....</foo>
383
             </additionalMetacata>
384
             The result will be (foo deosn't euqal access):
385
             <additionalMetadata>
386
					<describes>100</describes>
387
                     <metadata><foo>.....</foo></metadata>
388
             </additionalMetacata>
389
         2. <additionalMetadata>
390
					<describes>100</describes>
391
					<describes>200</describes>
392
                     <access>.....</access>
393
             </additionalMetacata>
394
            Both 100 and 200 are referenced ids of pysical/distribtuion or software/implementation/distribution.
395
            Since we moved the access part to distribution element. If multiple access rules are present 
396
            which reference the same distribution node, they are combined in th order they appear in 
397
            additionalMetadata sections. A conflict can occur here if  "order" attributes dont match. Fail
398
            with an erroro message.
399
            
400
            Since both are referenced id (and no conflict), we don't need to keep the info. 
401
           So the output is blank - remvoing the additionalMetadata tree.
402
         3. <additionalMetadata>
403
					<describes>300</describes>
404
					<describes>400</describes>
405
                     <access>.....</access>
406
             </additionalMetacata>
407
            300 is the referenced ids of pysical/distribtuion or software/implementation/distribution. 
408
            But 400 is not. So output will be:
409
            <additionalMetadata>
410
					<describes>400</describes>
411
                     <metadata><access>.....</access></metadata>
412
             </additionalMetacata>
413
            And we will give an warning message: message #2 referenced node is a not distribution id .
414
		4. <additionalMetadata>
415
                     <access>.....</access>
416
             </additionalMetacata>
417
            Since no describes, no access tree will move. So output will be:
418
            <additionalMetadata>
419
                     <metadata><access>.....</access></metadata>
420
             </additionalMetacata>
421
            And we will give an warning message:message #2 No distribution id in addtionalMetadata/describes 
422
            .
423
	-->
424
  <xsl:template mode="handle-additionalMetadata" match="*">
425
    <!-- this param for passing a suspicious node to an output message -->
426
    <xsl:param name="current_node"/>
427
    <!-- test if this additionalMetadata part has "access" element-->
428
    <xsl:variable name="accessCount" select="count(access | metadata/access)"></xsl:variable>
429
	
430
    <xsl:choose>
431
      <xsl:when test="$accessCount &lt; 1">
432
        <!-- no access tree here. Scenario 1 -->
433
        <additionalMetadata>
434
          <xsl:for-each select="./*">
435
            <xsl:choose>
436
              <xsl:when test="name()='describes'">
437
                <xsl:apply-templates mode="copy-no-ns" select="."></xsl:apply-templates>
438
              </xsl:when>
439
              <!--if it already has metadata tag under additionalMetadata, just copy it-->
440
              <xsl:when test="name()='metadata'">
441
                <xsl:apply-templates mode="copy-no-ns" select="."></xsl:apply-templates>
442
              </xsl:when>
443
              <xsl:otherwise>
444
                <metadata>
445
                  <xsl:apply-templates mode="copy-no-ns" select="."></xsl:apply-templates>
446
                </metadata>
447
              </xsl:otherwise>
448
            </xsl:choose>
449
          </xsl:for-each>
450
        </additionalMetadata>
451
      </xsl:when>
452
      <xsl:otherwise>
453
        <!--additionalMetadata has EML access child-->
454
        <xsl:variable name="describesCount" select="count(describes)"></xsl:variable>
455
        <xsl:choose>
456
          <xsl:when test="$describesCount=0">
457
            <!-- scenario 4 - only has access but no describes, leave it there-->
458
            <additionalMetadata>
459
              <xsl:for-each select="./*">
460
                <xsl:choose>
461
                  <xsl:when test="name()='metadata'">
462
                    <xsl:apply-templates mode="copy-no-ns" select="."></xsl:apply-templates>
463
                  </xsl:when>
464
                  <xsl:otherwise>
465
                    <metadata>
466
                      <xsl:apply-templates mode="copy-no-ns" select="."></xsl:apply-templates>
467
                    </metadata>
468
                  </xsl:otherwise>
469
                </xsl:choose>
470
              </xsl:for-each>
471
              <xsl:message terminate="no">
472
                <xsl:call-template name="output_message2_warn">
473
                  <xsl:with-param name="current_node" select="current()"></xsl:with-param>
474
                </xsl:call-template>
475
              </xsl:message>
476
            </additionalMetadata>
477
          </xsl:when>
478
          <xsl:otherwise>
479
            <!-- Scenario 2 and 3 -->
480
			 <xsl:variable name="describes" select="./describes"/>
481
            <xsl:call-template name="handle-describe-access-in-additional-metadata">
482
              <!--select node-set of describe which doesn't refer physical/distribtuion or software/implmentation/distribution and it doesn't have both "denyFirst" and "allowFirst"-->
483
              <xsl:with-param name="describes-list"
484
                select="./describes[(not(//physical/distribution/@id =.) and not(//software/implementation/distribution/@id = .)) or
485
				   ((//physical/distribution/@id =. or //software/implementation/distribution/@id = .) and (//additionalMetadata[describes = $describes and (access[@order='allowFirst'] or metadata/access[@order='allowFirst'])] and //additionalMetadata[describes = $describes and (access[@order='denyFirst'] or metadata/access[@order='denyFirst'])]))]"
486
              ></xsl:with-param>
487
            </xsl:call-template>
488
          </xsl:otherwise>
489
        </xsl:choose>
490
      </xsl:otherwise>
491
    </xsl:choose>
492
  </xsl:template>
493

    
494
  <!-- parameter desribes will have the node-set of "describe" which doesn't reference any physical/distribtuion or
495
		software/implmentation/distribution. If size of node-set is zero, the template will do nothing, in other it will
496
		remove the additionalMetadata. If the size is not zero, we will keep the desribes and access-->
497
  <xsl:template name="handle-describe-access-in-additional-metadata">
498
    <xsl:param name="describes-list"></xsl:param>
499
    <xsl:choose>
500
      <xsl:when test="count($describes-list)=0">
501
        <!--Scenario 2: do nothing since all desribes are reference to physical/distribtuion or software/implmentation/distribution-->
502
      </xsl:when>
503
      <xsl:otherwise>
504
        <!--Scenario 3: some desribes doesn't refer to physical/distribtuion or software/implmentation/distribution. We need to keep them-->
505
        <additionalMetadata>
506
          <xsl:call-template name="recursive-describes">
507
            <xsl:with-param name="describes" select="$describes-list"></xsl:with-param>
508
          </xsl:call-template>
509
          <metadata>
510
            <xsl:apply-templates mode="copy-no-ns" select="./access | ./metadata/access"
511
            ></xsl:apply-templates>
512
          </metadata>
513
        </additionalMetadata>
514
      </xsl:otherwise>
515
    </xsl:choose>
516
  </xsl:template>
517

    
518
  <!-- Use a recursive way to print out describes which doesn't refer physical/distribtuion or software/implmentation/distribution -->
519
  <xsl:template name="recursive-describes">
520
    <xsl:param name="describes"></xsl:param>
521
    <xsl:param name="index" select="1"></xsl:param>
522
    <xsl:choose>
523
      <!--finish-->
524
      <xsl:when test="$index > count($describes)">
525
        <!-- do nothing-->
526
      </xsl:when>
527
      <xsl:otherwise>
528
        <describes>
529
          <xsl:value-of select="$describes[$index]"></xsl:value-of>
530
        </describes>
531
        <xsl:call-template name="recursive-describes">
532
          <xsl:with-param name="describes" select="$describes"></xsl:with-param>
533
          <xsl:with-param name="index" select="$index + 1"></xsl:with-param>
534
        </xsl:call-template>
535
      </xsl:otherwise>
536
    </xsl:choose>
537
  </xsl:template>
538

    
539
  <!--Template to replace string "replace" by string "with" in given string "text"-->
540
  <xsl:template name="replace-string">
541
    <xsl:param name="text"></xsl:param>
542
    <xsl:param name="replace"></xsl:param>
543
    <xsl:param name="with"></xsl:param>
544
    <xsl:choose>
545
      <xsl:when test="contains($text,$replace)">
546
        <xsl:value-of select="substring-before($text,$replace)"></xsl:value-of>
547
        <xsl:value-of select="$with"></xsl:value-of>
548
        <xsl:call-template name="replace-string">
549
          <xsl:with-param name="text" select="substring-after($text,$replace)"></xsl:with-param>
550
          <xsl:with-param name="replace" select="$replace"></xsl:with-param>
551
          <xsl:with-param name="with" select="$with"></xsl:with-param>
552
        </xsl:call-template>
553
      </xsl:when>
554
      <xsl:otherwise>
555
        <xsl:value-of select="$text"></xsl:value-of>
556
      </xsl:otherwise>
557
    </xsl:choose>
558
  </xsl:template>
559

    
560
  <!-- 
561
    
562
    these templates output mesages for the user if an additionalMetdata section cant be moved. -->
563
  <!-- 
564
    this message for scenario 1, order attribute conflict -->
565
  <xsl:template name="output_message1_warn">
566
    <xsl:param name="current_node"/>
567
    <xsl:text>
568
      Warning:
569
      The EML 2.0.1 document you wish to transform has multiple access subtrees in addtionalMetadata 
570
      blocks which describe the same entity.  However, their "order" attributes do not match, so these 
571
      access rules cannot be combinded under the entity's distribution node. Please fix the incoming 
572
      (EML 2.0) document so that the  "order" attributes on all access nodes for an entity are the same.
573
      Example content to help locate the problem:     </xsl:text>
574
    <xsl:value-of select="$current_node"/>  </xsl:template>    
575
  <!-- 
576
    
577
    this message for scenario 4  -->
578
  <xsl:template name="output_message2_warn">
579
    <xsl:param name="current_node"/>
580
    <xsl:text>
581
      Warning: 
582
      This document doesn't follow  EML2.0.1 specs for including access trees. It appears to contain an
583
      additonalMetadata section with an access element, but there is no describes element referencing 
584
      the id of a physical/distribution or a software/implementation/distribution element (there might be 
585
      a reference to some other node, however). The rest of the document was successfully converted to 
586
      EML2.1, although the offending access tree was left as is. You should examine your incoming 
587
      document and change it to comply with EML 2.0.1 specs, or move this access tree using some 
588
      other method. 
589
      Example content to help locate a potential problem:     </xsl:text>
590
    <xsl:value-of select="$current_node"/>
591
  </xsl:template>
592
	
593
  <!-- message for empty string element-->
594
  <xsl:template name="output_message3_warn">
595
    <xsl:param name="current_node"/>
596
    <xsl:text>
597
      Warning:
598
      The EML 2.0.1 document has an empty string (or whitespace) in an element which cannot be empty in EML 2.1.0 sepcification - </xsl:text>
599
    <xsl:apply-templates select="$current_node" mode="get-full-path"/>
600
</xsl:template>    
601
	
602
	
603
	<!-- message for reminding  user  that the eml 210 document may be invalid-->
604
  <xsl:template name="output_message4_warn">
605
 
606
    <xsl:text>
607
      Warning:
608
      The EML 2.0.1 document has been transformed into an EML 2.1.0 document. However, you should check if it is valid. 
609
	  See http://knb.ecoinformatics.org/software/eml/eml-2.1.0/eml-210info.html for more information.</xsl:text>
610
    
611
</xsl:template>    
612
  <!-- 
613
    
614
    end of user message templates -->
615
	
616
	<!-- get full path of given element-->
617
    <xsl:template match="node()" mode="get-full-path">
618
      <xsl:for-each select="ancestor-or-self::*">
619
        <xsl:text>/</xsl:text><xsl:value-of select="name()" />
620
      </xsl:for-each>
621
    </xsl:template>
622

    
623

    
624

    
625

    
626

    
627
</xsl:stylesheet>