source: ndgCommon/trunk/ndg/common/xmldb/xquery/atom2NERCiso.xq @ 7885

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/ndgCommon/trunk/ndg/common/xmldb/xquery/atom2NERCiso.xq@7885
Revision 7885, 43.8 KB checked in by sdonegan, 9 years ago (diff)

Further updates to keywords and atom content handling

Line 
1(: CEDA ATOM to NERC Discovery Metadata Standard conversion :)
2
3(: Converts to DMS v0.6 October 2010:)
4
5(:
6Steve Donegan, CEDA RALSpace, 20/10/2010
7
8Notes:
9    1. Note georss and gml namespaces changed to match those present in CEDA ATOMs in bora.badc.rl.ac.uk eXist database
10:)
11(: eXist library :)
12import module namespace isolib='http://ndg.nerc.ac.uk/xquery/lib/iso_utilities' at 'xmldb:exist:///db/xquery/lib/Utilities/isoUtilities_xquery_lib.xquery';
13
14declare default element namespace 'http://www.isotc211.org/2005/gmd';
15
16declare namespace atom = 'http://www.w3.org/2005/Atom';
17declare namespace moles="http://ndg.nerc.ac.uk/schema/moles2beta";
18declare namespace f='http://ndg.nerc.ac.uk/moles/localfunctions';
19declare namespace georss = "http://www.georss.org/georss/10";
20declare namespace fn = "http://www.w3.org/2005/02/xpath-functions";
21declare namespace xhtml="http://www.w3.org/1999/xhtml";
22
23(: need the dif namespace as we are picking up organisationInfo from dif based record currently in Bora db :)
24declare namespace dif = 'http://gcmd.gsfc.nasa.gov/Aboutus/xml/dif/';
25
26(: other NS we need to produce the NERC  ISO :)
27declare namespace gmd='http://www.isotc211.org/2005/gmd';
28declare namespace xsi='http://www.w3.org/2001/XMLSchema-instance';
29declare namespace gco='http://www.isotc211.org/2005/gco';
30declare namespace gmx='http://www.isotc211.org/2005/gmx';
31declare namespace gml='http://www.opengis.net/gml';
32declare namespace xlink='http://www.w3.org/1999/xlink';
33
34(: Keep this in official lib version
35declare variable $targetCollection as xs:string := '/db/atoms/Published';
36declare variable $deploymentsDir as xs:string := '/deployments';
37declare variable $dataEntitiesDir as xs:string := '/data_entities';
38declare variable $repositoryIdentifier as xs:string := 'badc.nerc.ac.uk';
39declare variable $localIdentifier as xs:string := 'badc.nerc.ac.uk__ATOM__dataent_active';
40declare variable $dptTerm as xs:string := 'DPTTerm';
41declare variable $obsTerm as xs:string :=  'OBSTerm';
42declare variable $activityTerm as xs:string :=  'ACTIVITYTerm';
43declare variable $uriTerm as xs:string :=  'URITerm';
44declare variable $granuleTerm as xs:string :=  'GranuleTerm';
45:)
46
47
48(: Define the name of the metadata standard to be used in converted document :)
49declare variable $MetadataStandardName as xs:string := 'NERC Discovery Metadata Standard';
50declare variable $MetadataStandardCEDAPrefix as xs:string := 'NERC_DMS_0.7';
51declare variable $MetadataStandardVersion as xs:string := '0.7';
52
53(: CEDA eXist directory containing the data center organisation DIF snippets :)
54declare variable $organisationInfoDir as xs:string := '/db/atoms/resources';
55
56(: Development use only
57declare variable $targetCollection as xs:string := '/db/atoms/published/';
58declare variable $repositoryIdentifier as xs:string := 'neodc.nerc.ac.uk';
59declare variable $localIdentifier as xs:string := 'tag:badc.nerc.ac.uk,2009-12-10:/view/neodc.nerc.ac.uk__ATOM__dataent_12447304699327717'; :)
60
61(:Production use only:)
62declare variable $targetCollection as xs:string := 'TargetCollection';
63declare variable $repositoryIdentifier as xs:string := 'RepositoryID';
64declare variable $localIdentifier as xs:string := 'RepositoryID__ATOM__LocalID$';
65
66declare variable $dptTerm as xs:string := 'DPT - NOT YET SET UP/None/DPT';
67declare variable $obsTerm as xs:string :=  'OBS - NOT YET SET UP/None/OBS';
68declare variable $activityTerm as xs:string :=  'Activity - NOT YET SET UP/None/ACTIVITY';
69declare variable $granuleTerm as xs:string :=  'GRAN - NOT YET SET UP/None/GRANULE';
70declare variable $deploymentTerm as xs:string := 'NOT YET SET UP/None/Deployment';
71declare variable $uriTerm as xs:string :=  'URI';
72
73(: These two are unlikely to change :)
74declare variable $dataEntitiesDir as xs:string := 'data_entities';
75declare variable $deploymentsDir as xs:string := 'deployments';
76declare variable $deploymentDataDir as xs:string := 'deployment_data';
77
78(:declare variable $atomCollection as xs:string := concat('TargetCollection', $dataEntitiesDir, '/', 'RepositoryID'); :)
79declare variable $atomCollection as xs:string := concat($targetCollection, $dataEntitiesDir, '/', $repositoryIdentifier    );
80
81declare variable $currentDate as xs:string := substring(current-date() cast as xs:string,1,10);
82
83for $DE in collection($atomCollection)/atom:entry[matches(atom:id, $localIdentifier)]
84
85(:sort out complex variables here as easier to do here than embedded in the xQuery! :)
86
87(: set unique identifier as a variable :)   
88let $identifier := concat(string($DE/moles:entity/moles:molesISO/moles:providerID),':',$MetadataStandardCEDAPrefix,':', tokenize(string($DE/atom:id), '__ATOM__')[2])
89
90(: extract the CEDA Data Center ID :)
91let $cedaIdentifier := $DE/moles:entity/moles:molesISO/moles:providerID
92
93(:define string variable for publication and creation dates comprised of comma delimited list from ATOM elements:)
94let $publicationCreationDates := concat(data($DE/atom:published),"=",string('publication'),",",data($DE/moles:entity/moles:molesISO/moles:created),"=",string("creation"))
95
96return
97
98element gmd:MD_Metadata {
99   
100    element gmd:fileIdentifier {
101        element gco:CharacterString {
102            (: for CEDA purposes use main unique resource identifier here - element 6
103            concat(string($DE/moles:entity/moles:molesISO/moles:providerID),':NERC_v0.6:', tokenize(string($DE/atom:id), '__ATOM__')[2]):)
104            data($identifier)
105        }       
106     },
107     
108     (:Metadata_Language element 29:)
109     element gmd:language {
110     
111         (: TODO: CEDA supports some iso elements in atom, but needs provision for codelist values.  In this case "eng" :)
112         element gmd:LanguageCode {
113             attribute codeList {'http://www.loc.gov/standards/iso639-2/php/code_list.php'},
114             attribute codeListValue {'eng'},
115             data($DE/moles:entity/moles:molesISO/moles:metadataLanguage)         
116         }
117     },
118     
119     (: Resource Type element 4 :)
120     element gmd:hierarchyLevel {
121         element gmd:MD_ScopeCode {         
122             attribute codeList {'http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_ScopeCode'},
123             attribute codeListValue {'series'},
124             string('series')
125         
126         }
127     },
128
129    (: Element 22 Responsible Party - Metadata point of contact.  For CEDA purposes this will be the relevent helpdesk contact :)
130   
131     (: TODO: get this info from ATOM :)
132   
133    element gmd:contact
134    {
135        (:isolib:CI_ResponsibleParty(string("CEDA"), element individualName {string("")}, element positionName{string("CEDA Data Scientist")}, element role {string("pointOfContact")}, element phone {string("01235 778123")}, element addressLine {string("RALSpace, HSIC, Rutherford Appleton Laboratory")}, element city {string("Didcot")}, element postCode {string("OX11 0QX")}, element email{string("ceda@stfc.ac.uk")}):)
136        isolib:cedaDataCenter(string("pointOfContact"), $organisationInfoDir, $cedaIdentifier)
137    },
138   
139    (: Date of update of metadata - Element 26 :)
140    (: For CEDA this translates to the timestamp of the last update in the MOLES db, rather than the datestamp of the application of this conversion... WHICH means moles:updated:)
141    element gmd:dateStamp {
142        element gco:Date {
143            replace(string($DE/atom:updated),"Z","")
144        }
145    },
146   
147    (: Metadata Standard Name - Element  27 :)
148    (: For CEDA, this means the version of the NERC Discovery Metadata Standard this conversion is mapped to :)
149    element gmd:metadataStandardName {
150        element gco:CharacterString { data($MetadataStandardName)}
151    },
152   
153    (: Metadata Standard Version - Element 28 :)
154    element gmd:metadataStandardVersion {
155        element gco:CharacterString { data($MetadataStandardVersion)}
156    },
157   
158    (: Spatial Reference System - Element 15 :)
159    (: TODO: does CEDA need to include this in MOLES database? :)
160    element gmd:referenceSystemInfo {
161        element gmd:MD_ReferenceSystem {
162            element gmd:referenceSystemIdentifier {
163                element gmd:RS_Identifier {
164                    element gmd:code {
165                        (: TODO: find correct code! :)
166                        element gco:CharacterString { string("urn:ogc:def:crs:EPSG::27700")}
167                    }
168                }
169            }
170        }
171    },
172   
173    (: identificationInfo :)
174    element gmd:identificationInfo {
175        element gmd:MD_DataIdentification {
176            element gmd:citation {
177           
178                (: NOTE following elements handled by CI_Citation function :)
179           
180                (: Resource Title - Element 1 :)
181                (: Temporal Reference Date - Element 16 :)
182                (: TODO: check CEDA ATOM publication date has the same definition :)
183                (:Publication - Element 16.2 :)
184                (:Creation - Element 16.4 :)
185                (: Identifier - Element 6 :)
186                isolib:CI_Citation(data($DE/atom:title),$publicationCreationDates,$identifier,$DE/moles:entity/moles:molesISO/moles:providerID)
187               
188            },
189           
190            (: Abstract - Element 3 :)
191            element gmd:abstract {
192                element gco:CharacterString {data($DE/atom:summary)}                   
193            },
194           
195            (: Responsible party - Element 22 :)
196           
197            (: TODO: CEDA will need to better delineate this info as may need "originator" in addition to "dataPointOfContact" & metadataPointOfContact :)
198           
199            (:TODO: for CEDA purposes is organisationName sufficient?  Depends on type of pointOfContact as well as whats available
200           
201            UPDATE 08/02/11: If responsibleParties element present in the ATOM then use this to put in a ceda "data curator" pointOfContact -- can always add more via editor
202           
203            :)
204            if (exists($DE/moles:entity/moles:molesISO/moles:responsibleParties)) then
205           
206                for $responsibleParties in $DE/moles:entity/moles:molesISO/moles:responsibleParties/moles:responsibleParty
207               
208                let $name:=$responsibleParties/moles:name
209                let $uri:=$responsibleParties/moles:uri
210                let $role:=$responsibleParties/moles:role
211               
212                return
213                if (contains($name,"badc")) then
214               
215                    (: Mapping from ATOM title "Data Curator"... - shouldnt this be codelisted..?  :)
216                    if ($role = "Data Curator") then
217                        element gmd:pointOfContact {
218                            isolib:cedaDataCenter(string("custodian"), $organisationInfoDir, $name)
219                         }
220                     else ()
221                else ()
222                   
223            else (),
224           
225            (:originator:
226           
227            UPDATE (07/02/11): CEDA now collecting this in ATOm editor albeit only a name and url/email address - but this is all we have at the moment
228           
229            :)
230           
231            if (exists($DE/atom:author)) then
232           
233                for $author in $DE/atom:author
234               
235                    let $name:= $DE/atom:author/atom:name
236                    let $contact:=$DE/atom:author/atom:email
237                   
238                    return
239           
240                        (: Where only name supplied just supply empty text until we can get it factored in :)
241                       
242                        (: where an email is supplied.. format appropriate call to function :)
243                       
244                        element gmd:pointOfContact {
245                            isolib:CI_ResponsibleParty($name, element individualName {string("")}, element positionName{string("")}, element role {string("Originator")}, element phone {string("")}, element addressLine {string("")}, element city {string("")}, element postCode {string("")}, element email{string($contact)})
246                       
247                    }
248            else (),
249
250   
251         
252            (:
253            element gmd:pointOfContact
254            {               
255                (:isolib:CI_ResponsibleParty(string("CEDA"), element individualName {string("")}, element positionName{string("CEDA Data Scientist")}, element role {string("originator")}, element phone {string("01235 778123")}, element addressLine {string("RALSpace, HSIC, Rutherford Appleton Laboratory")}, element city {string("Didcot")}, element postCode {string("OX11 0QX")}, element email{string("ceda@stfc.ac.uk")}):)
256                isolib:cedaDataCenter(string("originator"), $organisationInfoDir, $cedaIdentifier)
257            },
258            :)
259            (:resourceMaintenance - Element # :)
260           
261            (:TODO: CEDA needs to record this resourceMaintenance info plus other INSPIRE related stuff HARDCODE for now! :)
262            (:DONE: CEDA now using values mapped to codelist and placed in $DE/moles:entity/moles:molesISO/moles:updateFrequency :)
263            element gmd:resourceMaintenance {
264                element gmd:MD_MaintenanceInformation {
265                    element gmd:maintenanceAndUpdateFrequency {
266                        element gmd:MD_MaintenanceFrequencyCode {
267                            attribute codeList {'http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_MaintenanceFrequencyCode'},
268                            attribute codeListValue {data($DE/moles:entity/moles:molesISO/moles:updateFrequency)},
269                            data($DE/moles:entity/moles:molesISO/moles:updateFrequency)                         
270                        }                   
271                    }
272                }
273            },
274           
275            (: Data Format :- Element #:)
276            (:TODO: need to get CEDA to evaluate this properly - codelist/vocab? 
277           
278            UPDATE (11/02/11) : can pull format from the atom:content xhtml section  BUT this is a restricted list from http://vocab.ndg.nerc.ac.uk/term/M010/-but its a cr@p list.
279           
280            :)
281           
282            (: this one is pulled from the CEDA ATOM :)
283              for $divContent in $DE/atom:content
284                let $content := isolib:extractAtomContent(string("cedacat:formats"),$divContent)
285                return
286                    if (string-length($content) > 0) then
287                     
288                        element gmd:resourceFormat {
289                            element gmd:MD_Format {
290                                element gmd:name {
291                                    element gco:CharacterString { string($content) }
292                                },
293                                element gmd:version {
294                                    attribute gco:nilReason {"inapplicable"}
295                                }
296                            }
297                        }
298                    else (), (: optional element so only fill if theres summat there :)
299           
300            (: Keywords - Element 11 :)
301           
302            (: Ensure NERC_DDC is in there :)
303           
304            (: TODO: CEDA/NERC - is this keyword in a vocab or codelist?/
305           
306            UPDATE 14/02/11:yes - use this http://vocab.ndg.nerc.ac.uk/term/N010/0/NDGO0003 - and use new method too.           
307            :)
308           
309            element gmd:descriptiveKeywords {
310                    element gmd:MD_Keywords {
311                        element gmd:keyword{
312                            element gmx:Anchor {
313                                attribute xlink:href {string("http://vocab.ndg.nerc.ac.uk/term/N010/0/")},
314                               
315                                (: use the unknown vocab reference.. this may show up on the portal as an error! :)
316                                attribute xlink:title {string("NDGO0003")},
317                                string("NERC_DDC")
318                            }                           
319                        }
320                    }
321                },
322           
323            (: Vertical Extent - Element 14:)
324           
325            (: TODO - CEDA have to implement vertical extent keywords - must take from L131 list on NDG vocab server.  :)
326                     
327            (: if vertical extent present - pull this through for now, notwithstanding whether its on the L131 list or not.. :)
328            for $keyword in $DE/moles:entity/moles:molesISO/moles:verticalExtent           
329            return
330                element gmd:descriptiveKeywords {
331                    element gmd:MD_Keywords {
332                        element gmd:keyword{
333                            element gmx:Anchor {
334                                attribute xlink:href {string("http://vocab.ndg.nerc.ac.uk/term/L131/3")},
335                               
336                                (: use the unknown vocab reference.. this may show up on the portal as an error! :)
337                                attribute xlink:title {string("UK")},
338                                data($keyword)
339                            }                           
340                        }
341                    }
342                },
343               
344            (: depending on whether BADC or NEODC record, add in some hardcoded VE keywords for good measure!:)
345             
346             if (contains($cedaIdentifier,"badc")) then           
347               element gmd:descriptiveKeywords {
348                    element gmd:MD_Keywords {
349                        element gmd:keyword{
350                            element gmx:Anchor {
351                                attribute xlink:href {string("http://vocab.ndg.nerc.ac.uk/term/L131/3")},
352                                attribute xlink:title {string("AT")},
353                                string("atmosphere")
354                            }                           
355                        }
356                    }
357                }           
358            else (),           
359           
360            if (contains($cedaIdentifier,"neodc")) then           
361                element gmd:descriptiveKeywords {
362                    element gmd:MD_Keywords {
363                        element gmd:keyword{
364                            element gmx:Anchor {
365                                attribute xlink:href {string("http://vocab.ndg.nerc.ac.uk/term/L131/3")},
366                                attribute xlink:title {string("UK")},
367                                string("unknown")
368                            }                           
369                        }
370                    }
371                }           
372            else (),
373           
374            (: INSPIRE keywords :)
375           
376            (: TODO: CEDA - need to have info on INSPIRE themes available in the CEDA MOLES db - hardwire for now
377           
378            Update: freetext field available in editor now - still need to map this to a vocab...
379           
380            PROBLEM 14/02/11: lack of suitable GEMET keywords for CEDA datasets/themes?
381           
382            :)
383           
384            if (contains($cedaIdentifier,"badc")) then           
385               element gmd:descriptiveKeywords {
386                element gmd:MD_Keywords {
387                    element gmd:keyword {
388                        element gco:CharacterString { string("Atmospheric conditions") }
389                    },
390                    element gmd:thesaurusName {                   
391                        isolib:CI_Citation(string('GEMET - INSPIRE themes, version 1.0'),concat($currentDate,"=",string('publication')),string(""),string(""))
392                    }
393                }
394            }
395            else (),
396           
397            if (contains($cedaIdentifier,"badc")) then           
398               element gmd:descriptiveKeywords {
399                element gmd:MD_Keywords {
400                    element gmd:keyword {
401                        element gco:CharacterString { string("Meteorological geographical features") }
402                    },
403                    element gmd:thesaurusName {                   
404                        isolib:CI_Citation(string('GEMET - INSPIRE themes, version 1.0'),concat($currentDate,"=",string('publication')),string(""),string(""))
405                    }
406                }
407            }
408            else (),
409           
410            if (contains($cedaIdentifier,"neodc")) then           
411               element gmd:descriptiveKeywords {
412                element gmd:MD_Keywords {
413                    element gmd:keyword {
414                        element gco:CharacterString { string("Orthoimagery") }
415                    },
416                    element gmd:thesaurusName {                   
417                        isolib:CI_Citation(string('GEMET - INSPIRE themes, version 1.0'),concat($currentDate,"=",string('publication')),string(""),string(""))
418                    }
419                }
420            }
421            else (),
422           
423           
424            (: TODO: CEDA - need to properly quantify keywords/parameters to actual vocabs.  For now map category attribute "label" to  keyword value in gmx:anchor and the scheme to xlink:href attritubte and term to title. 
425            follow medin example for nerc harvesting keyword.  This seriously needs tidying up
426           
427            UPDATE (07/02/11): do not take any definitions where the term="NULL" or if the word "ATOM" is in the Category, or "0" as all nonsensical and relict from previous mungings in the old pipeline
428           
429            :)
430            for $keyword in $DE/atom:category
431            let $term:=$keyword/@term
432            let $label:=$keyword/@label
433            let $scheme:=$keyword/@scheme
434            return
435            if (not(contains($term,"NULL")) and not(contains($term,"ATOM")) and not($term="0")) then
436                element gmd:descriptiveKeywords {
437                    element gmd:MD_Keywords {
438                        element gmd:keyword{
439                            element gmx:Anchor {
440                                attribute xlink:href {data($scheme)},
441                                attribute xlink:title {data($term)},
442                                data($label)
443                            }                           
444                        }
445                    }
446                }
447             else (),
448           
449            (: Conditions applying to access and use - Element 21 :)
450            (: TODO: CEDA doesnt record this in ATOM & its Mandatory.  Hardcode for now
451           
452            UPDATE 11/02/11: This information is now held in the atom:content XHTML - use new function to extract text and place it here..
453           
454            NOTE - similar info to element 20 accessConstraints and all lumped together in the atom:content so use the same here, but if none is detected put "no conditions apply"
455                   
456            :)
457         
458              for $divContent in $DE/atom:content
459                let $content := isolib:extractAtomContent(string("cedacat:access-restricted"),$divContent)
460                return
461                    if (string-length($content) > 0) then
462                                         
463                        element gmd:resourceConstraints {
464                            element gmd:MD_Constraints {
465                                element gmd:useLimitation {
466                                    element gco:CharacterString {string("Restrictions Apply")}
467                                }
468                            }
469                        }                   
470                   
471                    else
472                   
473                       (: Can't detect any access restrictions so to be safe use otherRestrictions :)
474           
475                        (: element 20 first :)
476                        element gmd:resourceConstraints {
477                            element gmd:MD_Constraints {
478                                element gmd:useLimitation {
479                                    element gco:CharacterString {string("no conditions apply")}
480                                }
481                            }
482                        },
483           
484            (: Limitations on Public Access - Element 20 :)           
485            (: TODO: CEDA doesnt record this in ATOM - & its Mandatory.  Hardcode for now
486           
487            UPDATE 11/02/11: This information is now held in the atom:content XHTML - use new function to extract text and place it here..
488           
489            (operation notes: if text found, then stick in an appropriate codeList value codeList value -
490           
491            :)
492           
493            for $divContent in $DE/atom:content
494                let $content := isolib:extractAtomContent(string("cedacat:access-restricted"),$divContent)
495                return
496                    if (string-length($content) > 0) then
497                                     
498                        (: element 21 now :)
499                        element gmd:resourceConstraints {
500                            element gmd:MD_LegalConstraints {
501                                element gmd:accessConstraints {
502                                    element gmd:MD_RestrictionCode {
503                           
504                                     (:TODO: CEDA will need link to this codelist for this element :)
505                                    attribute codeList {'http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_RestrictionCode'},
506                                    attribute codeListValue {'otherRestictions'},
507                                    string("otherRestrictions")                       
508                                    }
509                                },
510                                element gmd:otherConstraints {
511                                    element gco:CharacterString { string($content)}
512                                }
513                            }
514                        }
515                   
516                    else
517                   
518                       (: Can't detect any access restrictions so to be safe use otherRestrictions :)
519                               
520                        element gmd:resourceConstraints {
521                            element gmd:MD_LegalConstraints {
522                                element gmd:accessConstraints {
523                                    element gmd:MD_RestrictionCode {
524                           
525                                     (:TODO: CEDA will need link to this codelist for this element :)
526                                    attribute codeList {'http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_RestrictionCode'},
527                                    attribute codeListValue {'otherRestictions'},
528                                    string("otherRestrictions")                       
529                                    }
530                                },
531                                element gmd:otherConstraints {
532                                    element gco:CharacterString { string("Please refer to the dataset homepage for further information")}
533                                }
534                            }
535                        },
536           
537            (: Spatial Resolution - Element 18 :)
538           
539            (: TODO: CEDA doesnt record this in ATOM yet & its Mandatory: Hardcode for now to value of "0"...
540           
541            UPDATE - CEDA now recording these values as open text - Should be M where known for INSPIRE...
542           
543            :)
544           
545            element gmd:spatialResolution {
546                element gmd:MD_Resolution {
547                    element gmd:distance {
548                        if (exists($DE/moles:entity/moles:molesISO/moles:spatialResolution)) then
549                        element gmd:distance {
550                       
551                            (: TODO: CEDA only has open text field - will need to get the correct EPSG code for this.. hardcode for now.. :)
552                            attribute uom {"urn:ogc:def:uom:EPSG::9001"},
553                            data($DE/moles:entity/moles:molesISO/moles:spatialResolution)
554                        }
555                        else
556                        element gmd:distance {
557                            attribute gco:nilReason {"inapplicable"}
558                        }
559                    }
560                }           
561            },
562           
563            (: Resource Langauge - Element 8 :)
564            (:TODO: CEDA will need to include this element if any textual resource for the dataset - hardcode to english for now :)
565            element gmd:language {
566                element gmd:LanguageCode {
567                    attribute codeList {'http://www.loc.gov/standards/iso639-2/php/code_list.php'},
568                    attribute codeListValue {'eng'},
569                    string("English")
570                }
571            },
572           
573            (: Topic Category - Element 9:)
574            (:TODO: CEDA will also need to include this information as mandatory for datasets.  For now, hardcoded to "Geoscientific Information"
575           
576            UPDATE - still needs to be hardcoded as npt supported by DSR round1 editor updates, but use badc/neodc specific categories that are better descriptive of data
577           
578            :)
579           
580            if (contains($cedaIdentifier,"badc")) then           
581                element gmd:topicCategory {
582                    element gmd:MD_TopicCategoryCode {string("climatologyMeteorologyAtmosphere")}
583                }               
584            else (),           
585           
586            if (contains($cedaIdentifier,"neodc")) then           
587                element gmd:topicCategory {
588                    element gmd:MD_TopicCategoryCode {string("imageryBaseMapsEarthCover")}
589                }               
590            else (),
591            element gmd:topicCategory {
592                    element gmd:MD_TopicCategoryCode {string("environment")}
593                },
594           
595           
596            (: TODO: Many CEDA datasets don't have boundingBox info - MAndatory for compliancy.. :)
597             element gmd:extent {
598                element gmd:EX_Extent {
599               
600                     (:Extent - Bounding Box - Element 12 (note difference from an actual extent - i.e. ICES sea areas:)
601               
602                    if (exists($DE/georss:where)) then
603                        for $boundingBox in $DE/georss:where
604                        return
605                            element gmd:geographicElement {
606                                element gmd:EX_GeographicBoundingBox {                                                   
607                                    element gmd:westBoundLongitude {
608                                        element gco:Decimal {
609                                            data(tokenize(string($boundingBox/gml:Envelope/gml:lowerCorner), ' ')[1])
610                                        }
611                                    },
612                                    element gmd:eastBoundLongitude {
613                                        element gco:Decimal {
614                                            data(tokenize(string($boundingBox/gml:Envelope/gml:upperCorner), ' ')[1])
615                                        }
616                                    },
617                                    element gmd:southBoundLatitude {
618                                        element gco:Decimal {
619                                            data(tokenize(string($boundingBox/gml:Envelope/gml:lowerCorner), ' ')[2])
620                                        }
621                                    },
622                                    element gmd:northBoundLatitude {
623                                        element gco:Decimal {
624                                            data(tokenize(string($boundingBox/gml:Envelope/gml:upperCorner), ' ')[2])
625                                        }
626                                    }
627                                }
628                            }
629                        else (),
630                       
631                        (: Temporal Reference - Element 16.1 :)
632                        (: TODO: CEDA - mandatory element yet not all dataEntities have this recorded...
633                            AND - ATOM doesnt distinguish a single date as either start or end!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  blimey.
634                           
635                            UPDATE: NERC DMS now specifiies that "nilReason" be specified where data is unavailable.  Following code now deals with crappy ATOM date handling                           
636                        :)
637                       
638                        element gmd:temporalElement {
639                            element gmd:EX_TemporalExtent {
640                                if (exists($DE/moles:temporalRange)) then
641                                    for $dates in $DE/moles:temporalRange
642                                   
643                                    (:Need to isolate distinct start and end dates here, and if nothing in them detect and enter gco:nilReason="unknown" -all this down to damn stupid way of handling temporal data in ATOM!:)
644                                    let $isRange:=contains(string($dates),"/")
645                                    let $rangeStringLength:=string-length(string($dates))
646                                    let $rangeStartDate:=tokenize(string($dates), '/')[1]
647                                    let $rangeEndDate:=tokenize(string($dates), '/')[2]
648                                   
649                                    return                                       
650                                        element gmd:extent {
651                                           
652                                                if ($isRange) then
653                                                    element gml:TimePeriod {
654                                                       
655                                                        if (string-length($rangeStartDate) >1) then                                                             
656                                                            element gml:beginPosition {
657                                                                 data ($rangeStartDate)
658                                                             }
659                                                        else
660                                                            element gml:beginPosition {
661                                                                attribute gco:nilReason {"unknown"}
662                                                            },
663                                                         
664                                                         if (string-length($rangeEndDate) >1) then                                                             
665                                                            element gml:endPosition {
666                                                                 data ($rangeEndDate)
667                                                             }
668                                                        else
669                                                            element gml:endPosition {
670                                                                attribute gco:nilReason {"unknown"}
671                                                            }                                                 
672                                                        }
673                                                       
674                                                 else
675                                                     (:if not a range, then the atom editor only allows begin position - but check that a value is entered as might be blank!:)
676                                                     if ($rangeStringLength > 1) then
677                                                         element gml:TimePeriod {                                           
678                                                            element gml:beginPosition {
679                                                                data ($dates)
680                                                            },                                               
681                                                            element gml:endPosition {
682                                                                attribute gco:nilReason {"unknown"}
683                                                            }
684                                                         }
685                                                     else
686                                                         element gml:TimePeriod {                                           
687                                                             element gml:beginPosition {
688                                                                   attribute gco:nilReason {"unknown"}
689                                                            },                                               
690                                                              element gml:endPosition {
691                                                                   attribute gco:nilReason {"unknown"}
692                                                            }
693                                                        }
694                                           
695                                        }
696                                else ()
697                            }                       
698                        }
699                    }                       
700             }, (: /extent:)
701         
702         
703          (: supplementalInformation - can pull some info out of the atom:content and put here..:)
704         
705          for $divContent in $DE/atom:content
706                let $content := isolib:extractAtomContent(string("cedacat:citation"),$divContent)
707                return
708                    if (string-length($content) > 0) then
709         
710                      element gmd:supplementalInformation {
711                        element gco:CharacterString {string($content)}
712                      }
713                   else ()
714             
715          }
716    },  (: /identificationInfo :)
717   
718    (: distributionInfo :)
719    element gmd:distributionInfo {
720        element gmd:MD_Distribution {
721   
722            (: The ISO 19115 Constraints require this element! :)
723            element gmd:distributionFormat {
724                attribute gco:nilReason {"inapplicable"}       
725            },
726       
727            (: Responsible Party - Element 22 - Mandatory for datasets! NOTE role=distributor so ok to hardwire as CEDA :)
728            element gmd:distributor {
729                element gmd:MD_Distributor{
730                    element gmd:distributorContact {                                               
731                        isolib:cedaDataCenter(string("distributor"), $organisationInfoDir, $cedaIdentifier)
732                    }
733                }           
734            },
735           
736            (: Resource Locator - Element 5.  NOTE for NERC onlineResource must be provided for datasets:)
737           
738            (: TODO: For CEDA purposes - ensure link to dataset browser is explicitly included in info is in ATOM - indicated by attribute val "Data Directory" :)
739           
740            (:TODO: CEDA - must specifiy correct choice of onlineresource from vocab/codelist - hardwired for "download" right now. :
741           
742            UPDATE Feb 2011 - CEDA Discovery records must only have data download and dataset homepage links (i.e. get rid of all deployment links etc)
743           
744            :)
745           
746            for $link in $DE/atom:link
747                let $url:= $link/@href
748                let $relation:= $link/@rel
749                let $title:= $link/@title
750                return
751                   
752                    (: Check for ATOM codeList values and convert as necessary..   :)                 
753                    if (contains(string($relation),string("DOWNLOAD"))) then
754                 
755                         isolib:transferOptions (string($url), string(replace(string($relation),"NOT YET SET UP/","")), string($title), string("download"))
756                         
757                    else if ($relation = "self") then
758                        (: For NERC DMS, download must only be used where online data is actually available.  So, until CEDA can link to the correct codelist and get these vals into the ATOM we must do this.. :)
759                        isolib:transferOptions (string($url), string("CEDA Dataset Homepage"), string($title), string("information"))
760                    else ()
761                     
762        }, (: /distributionInfo :)
763       
764        (: Lineage and INSPIRE conformity elements - Element 25 :)
765        element gmd:dataQualityInfo {
766            element gmd:DQ_DataQuality {
767               
768                (: Scope -required by ISO19115 :)
769                element gmd:scope {
770                    element gmd:DQ_Scope {
771                        element gmd:level {
772                            element gmd:MD_ScopeCode {
773                       
774                                (: TODO: as part of CEDA creep towards INSPIRE conformity, this codelist should be listed:)
775                                attribute codeList {'http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/gmxCodelists.xml#MD_ScopeCode'},
776                                attribute codeListValue {'dataset'},
777                                string("dataset")
778                            }
779                        }
780                    }
781                },
782               
783                (: Lineage - Element 17 :)
784               
785                (: TODO: CEDA : doesnt currently record this information, so hardwire for now - BUT can use ATOM content with CEDA basic strapline  :)
786                (: DONE - CEDA now records in ATOM this info in moles:entity/moles:molesISO.  ALSO some ATOMS have "quality" info - string this together with lineage info :)
787                if (exists($DE/moles:entity/moles:molesISO/moles:lineage))
788                then
789                element gmd:lineage {
790                    element gmd:LI_Lineage {
791                        element gmd:statement {
792                            element gco:CharacterString {
793                                if (exists($DE/moles:entity/moles:molesISO/moles:quality)) then
794                                    concat(data($DE/moles:entity/moles:molesISO/moles:lineage)," ; ",data($DE/moles:entity/moles:molesISO/moles:quality))
795                                else
796                                    data($DE/moles:entity/moles:molesISO/moles:lineage)
797                            }
798                        }
799                    }
800                }               
801                else
802                (: return standard bit if lineage not available on this atom :)
803                element gmd:lineage {
804                    element gmd:LI_Lineage {
805                        element gmd:statement {
806                            element gco:CharacterString {
807                                data(concat(string("This Dataset has been acquired by CEDA and is hosted by agreement from the data originator.")," ",$DE/atom:content/xhtml:div))
808                            }
809                        }
810                    }
811                }
812               
813               
814            }       
815        } (: /dataQualityInfo :)
816    }
817    }
818   
819
Note: See TracBrowser for help on using the repository browser.