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

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

Updated handling of decimals of atom spatial coverage into ISO extent

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