ld4l-works_rdf 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +25 -0
  4. data/.travis.yml +14 -0
  5. data/CHANGES.md +3 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +170 -0
  9. data/Rakefile +2 -0
  10. data/ld4l-works_rdf.gemspec +42 -0
  11. data/lib/ld4l/works_rdf.rb +131 -0
  12. data/lib/ld4l/works_rdf/configuration.rb +41 -0
  13. data/lib/ld4l/works_rdf/models/bibframe/bibframe_identifier.rb +17 -0
  14. data/lib/ld4l/works_rdf/models/bibframe/bibframe_instance.rb +23 -0
  15. data/lib/ld4l/works_rdf/models/bibframe/bibframe_organization.rb +16 -0
  16. data/lib/ld4l/works_rdf/models/bibframe/bibframe_person.rb +16 -0
  17. data/lib/ld4l/works_rdf/models/bibframe/bibframe_place.rb +16 -0
  18. data/lib/ld4l/works_rdf/models/bibframe/bibframe_provider.rb +18 -0
  19. data/lib/ld4l/works_rdf/models/bibframe/bibframe_title.rb +18 -0
  20. data/lib/ld4l/works_rdf/models/bibframe/bibframe_work.rb +16 -0
  21. data/lib/ld4l/works_rdf/models/bibo/bibo_book.rb +19 -0
  22. data/lib/ld4l/works_rdf/models/bibo/bibo_document.rb +14 -0
  23. data/lib/ld4l/works_rdf/models/bibo/vivo_authorship.rb +15 -0
  24. data/lib/ld4l/works_rdf/models/bibo/vivo_book.rb +18 -0
  25. data/lib/ld4l/works_rdf/models/generic_work.rb +13 -0
  26. data/lib/ld4l/works_rdf/models/schema/oclc_schema_book.rb +16 -0
  27. data/lib/ld4l/works_rdf/models/schema/schema_book.rb +23 -0
  28. data/lib/ld4l/works_rdf/models/schema/schema_person.rb +17 -0
  29. data/lib/ld4l/works_rdf/models/schema/schema_publisher.rb +15 -0
  30. data/lib/ld4l/works_rdf/models/work_metadata.rb +212 -0
  31. data/lib/ld4l/works_rdf/services/attempt_generic_metadata_extraction.rb +41 -0
  32. data/lib/ld4l/works_rdf/services/conversion_services/get_rdfxml_from_marcxml.rb +44 -0
  33. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/modules/module.ErrorCodes.xqy +56 -0
  34. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/modules/module.MARCXML-2-MADSRDF.xqy +1702 -0
  35. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/modules/module.MARCXML-2-RecordInfoRDF.xqy +216 -0
  36. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/modules/module.MARCXMLBIB-2-BIBFRAME.xqy +140 -0
  37. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/modules/module.MARCXMLBIB-BFUtils.xqy +3287 -0
  38. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/modules/module.MBIB-2-BIBFRAME-Shared.xqy +4112 -0
  39. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/modules/module.MBIB-Default-2-BF.xqy +61 -0
  40. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/modules/module.MBIB-NotatedMusic-2-BF.xqy +105 -0
  41. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/modules/module.RDFXML-2-ExhibitJSON.xqy +119 -0
  42. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/modules/module.RDFXML-2-JSON.xqy +193 -0
  43. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/modules/module.RDFXML-2-Ntriples.xqy +276 -0
  44. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/modules/module.RDFXMLnested-2-flat.xqy +380 -0
  45. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/xbin/ml.xqy +239 -0
  46. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/xbin/saxon.xqy +134 -0
  47. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/xbin/zorba.xqy +359 -0
  48. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/xbin/zorba2-0.xqy +249 -0
  49. data/lib/ld4l/works_rdf/services/conversion_services/marc2bibframe/xbin/zorba3-0.xqy +362 -0
  50. data/lib/ld4l/works_rdf/services/conversion_services/saxon/saxon9he.jar +0 -0
  51. data/lib/ld4l/works_rdf/services/get_metadata_from_marcxml_uri.rb +43 -0
  52. data/lib/ld4l/works_rdf/services/get_metadata_from_oclc_uri.rb +25 -0
  53. data/lib/ld4l/works_rdf/services/get_metadata_from_solr_query.rb +29 -0
  54. data/lib/ld4l/works_rdf/services/get_metadata_from_vivo_uri.rb +25 -0
  55. data/lib/ld4l/works_rdf/services/get_model_from_uri.rb +62 -0
  56. data/lib/ld4l/works_rdf/services/metadata_services/get_metadata_from_bibframe_models.rb +60 -0
  57. data/lib/ld4l/works_rdf/services/metadata_services/get_metadata_from_bibo_model.rb +42 -0
  58. data/lib/ld4l/works_rdf/services/metadata_services/get_metadata_from_generic_model.rb +41 -0
  59. data/lib/ld4l/works_rdf/services/metadata_services/get_metadata_from_oclc_model.rb +42 -0
  60. data/lib/ld4l/works_rdf/services/metadata_services/get_metadata_from_solr_doc.rb +67 -0
  61. data/lib/ld4l/works_rdf/services/metadata_services/get_metadata_from_vivo_model.rb +45 -0
  62. data/lib/ld4l/works_rdf/services/metadata_services/set_error_in_metadata.rb +27 -0
  63. data/lib/ld4l/works_rdf/services/model_services/populate_bibframe_models_from_repository.rb +46 -0
  64. data/lib/ld4l/works_rdf/services/model_services/populate_generic_model_from_repository.rb +30 -0
  65. data/lib/ld4l/works_rdf/services/model_services/populate_oclc_model_from_repository.rb +27 -0
  66. data/lib/ld4l/works_rdf/services/model_services/populate_vivo_model_from_repository.rb +27 -0
  67. data/lib/ld4l/works_rdf/services/negotiation_services/get_marcxml_from_uri.rb +35 -0
  68. data/lib/ld4l/works_rdf/services/negotiation_services/get_rdfxml_from_uri.rb +37 -0
  69. data/lib/ld4l/works_rdf/services/negotiation_services/get_solr_results_from_solr_query.rb +35 -0
  70. data/lib/ld4l/works_rdf/services/negotiation_services/get_turtle_from_uri.rb +37 -0
  71. data/lib/ld4l/works_rdf/services/negotiation_services/response_header.rb +51 -0
  72. data/lib/ld4l/works_rdf/services/repository_services/populate_graph_from_rdfxml.rb +22 -0
  73. data/lib/ld4l/works_rdf/services/repository_services/populate_graph_from_turtle.rb +21 -0
  74. data/lib/ld4l/works_rdf/services/repository_services/populate_repository_from_graph.rb +25 -0
  75. data/lib/ld4l/works_rdf/version.rb +5 -0
  76. data/lib/ld4l/works_rdf/vocab/bf.rb +29 -0
  77. data/lib/ld4l/works_rdf/vocab/bgn.rb +5 -0
  78. data/lib/ld4l/works_rdf/vocab/bibo.rb +10 -0
  79. data/lib/ld4l/works_rdf/vocab/library.rb +6 -0
  80. data/lib/ld4l/works_rdf/vocab/vitro.rb +5 -0
  81. data/lib/ld4l/works_rdf/vocab/vivo.rb +11 -0
  82. data/spec/ld4l/works_rdf/configuration_spec.rb +166 -0
  83. data/spec/ld4l/works_rdf/models/books/vivo_book_rdf_spec.rb +267 -0
  84. data/spec/ld4l/works_rdf/services/get_metadata_from_uri_spec.rb +39 -0
  85. data/spec/ld4l/works_rdf/services/get_model_from_uri_spec.rb +34 -0
  86. data/spec/ld4l/works_rdf_spec.rb +53 -0
  87. data/spec/spec_helper.rb +26 -0
  88. metadata +321 -0
@@ -0,0 +1,249 @@
1
+ xquery version "3.0";
2
+
3
+ (:
4
+ : Module Name: MARC/XML BIB 2 BIBFRAME RDF using Saxon
5
+ :
6
+ : Module Version: 1.0
7
+ :
8
+ : Date: 2012 December 03
9
+ :
10
+ : Copyright: Public Domain
11
+ :
12
+ : Proprietary XQuery Extensions Used: Zorba (expath)
13
+ :
14
+ : Xquery Specification: January 2007
15
+ :
16
+ : Module Overview: Transforms MARC/XML Bibliographic records
17
+ : to RDF conforming to the BIBFRAME model. Outputs RDF/XML,
18
+ : N-triples, or JSON.
19
+ :
20
+ : adding holdings capability; allow <marcxml:collection> with multiple records,some holdigns, related to bibs on 004
21
+ :
22
+ : Run: zorba -i -q file:///location/of/zorba.xqy -e marcxmluri:="http://location/of/marcxml.xml" -e serialization:="rdfxml" -e baseuri:="http://your-base-uri/"
23
+ : Run: zorba -i -q file:///location/of/zorba.xqy -e marcxmluri:="../location/of/marcxml.xml" -e serialization:="rdfxml" -e baseuri:="http://your-base-uri/"
24
+ :)
25
+
26
+ (:~
27
+ : Transforms MARC/XML Bibliographic records
28
+ : to RDF conforming to the BIBFRAME model. Outputs RDF/XML,
29
+ : N-triples, or JSON.
30
+ :
31
+ : @author Nate Trail (ntra@loc.gov)
32
+ : @author Kevin Ford (kefo@loc.gov)
33
+ : @since December 17, 2014
34
+ : @version 1.0
35
+ :)
36
+
37
+ (: IMPORTED MODULES :)
38
+ import module namespace http = "http://www.zorba-xquery.com/modules/http-client";
39
+ import module namespace file = "http://expath.org/ns/file";
40
+ import module namespace parsexml = "http://www.zorba-xquery.com/modules/xml";
41
+ import schema namespace parseoptions = "http://www.zorba-xquery.com/modules/xml-options";
42
+
43
+
44
+
45
+ import module namespace marcbib2bibframe = "info:lc/id-modules/marcbib2bibframe#" at "../modules/module.MARCXMLBIB-2-BIBFRAME.xqy";
46
+ import module namespace rdfxml2nt = "info:lc/id-modules/rdfxml2nt#" at "../modules/module.RDFXML-2-Ntriples.xqy";
47
+ import module namespace rdfxml2json = "info:lc/id-modules/rdfxml2json#" at "../modules/module.RDFXML-2-JSON.xqy";
48
+ import module namespace bfRDFXML2exhibitJSON = "info:lc/bf-modules/bfRDFXML2exhibitJSON#" at "../modules/module.RDFXML-2-ExhibitJSON.xqy";
49
+ import module namespace RDFXMLnested2flat = "info:lc/bf-modules/RDFXMLnested2flat#" at "../modules/module.RDFXMLnested-2-flat.xqy";
50
+
51
+ (: NAMESPACES :)
52
+ declare namespace marcxml = "http://www.loc.gov/MARC21/slim";
53
+ declare namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
54
+ declare namespace rdfs = "http://www.w3.org/2000/01/rdf-schema#";
55
+
56
+ declare namespace bf = "http://bibframe.org/vocab/";
57
+ declare namespace madsrdf = "http://www.loc.gov/mads/rdf/v1#";
58
+ declare namespace relators = "http://id.loc.gov/vocabulary/relators/";
59
+ declare namespace identifiers = "http://id.loc.gov/vocabulary/identifiers/";
60
+ declare namespace notes = "http://id.loc.gov/vocabulary/notes/";
61
+
62
+ declare namespace an = "http://www.zorba-xquery.com/annotations";
63
+ declare namespace httpexpath = "http://expath.org/ns/http-client";
64
+
65
+ (:~
66
+ : This variable is for the base uri for your Authorites/Concepts.
67
+ : It is the base URI for the rdf:about attribute.
68
+ :
69
+ :)
70
+ declare variable $baseuri as xs:string external := "http://example.org/";
71
+
72
+ (:~
73
+ : This variable determines whether bnodes should identify resources instead of
74
+ : http URIs, except for the "main" Work derived from each MARC record. At this time,
75
+ : the "main" Work must be identified by HTTP URI (using the $baseuri variable
76
+ : above).
77
+ :
78
+ :)
79
+ declare variable $usebnodes as xs:string external := "false";
80
+
81
+ (:~
82
+ : This variable is for the MARCXML location - externally defined.
83
+ :)
84
+ declare variable $marcxmluri as xs:string external;
85
+
86
+ (:~
87
+ : This variable is for desired serialzation. Expected values are: rdfxml (default), rdfxml-raw, ntriples, json, exhibitJSON, log
88
+ :)
89
+ declare variable $serialization as xs:string external := "rdfxml";
90
+
91
+ (:~
92
+ : This variable is for desired serialzation. Expected values are: rdfxml (default), rdfxml-raw, ntriples, json, exhibitJSON
93
+ :)
94
+ declare variable $resolveLabelsWithID as xs:string external := "false";
95
+
96
+ (:~
97
+ Performs an http get but does not follow redirects
98
+
99
+ $l as xs:string is the label
100
+ $scheme as xs:string is the scheme
101
+ :)
102
+ declare %an:sequential function local:http-get(
103
+ $label as xs:string,
104
+ $scheme as xs:string
105
+ )
106
+ {
107
+ let $l := fn:encode-for-uri($label)
108
+ let $request :=
109
+ http:send-request(
110
+ <httpexpath:request
111
+ method="GET"
112
+ href="http://id.loc.gov/authorities/{$scheme}/label/{$l}"
113
+ follow-redirect="false"/>,
114
+ (),
115
+ ()
116
+ )
117
+ return $request
118
+ };
119
+
120
+ (:~
121
+ Outputs a resource, replacing verbose hasAuthority property
122
+ with a simple rdf:resource pointer
123
+
124
+ $resource as element() is the resource
125
+ $authuri as xs:string is the authority URI
126
+ :)
127
+ declare %an:nondeterministic function local:generate-resource(
128
+ $r as element(),
129
+ $authuri as xs:string
130
+ )
131
+ {
132
+ element { fn:name($r) } {
133
+ $r/@*,
134
+ $r/*[fn:name() ne "bf:hasAuthority"],
135
+ element bf:hasAuthority {
136
+ attribute rdf:resource { $authuri }
137
+ }
138
+ }
139
+ };
140
+
141
+
142
+ (:~
143
+ Tries to resolve Labels to URIs
144
+
145
+ $resource as element() is the resource
146
+ $authuri as xs:string is the authority URI
147
+ :)
148
+ declare %an:sequential function local:resolve-labels(
149
+ $flatrdfxml as element(rdf:RDF)
150
+ )
151
+ {
152
+ let $resources :=
153
+ for $r in $flatrdfxml/*
154
+ let $n := fn:local-name($r)
155
+ let $scheme :=
156
+ if ( fn:matches($n, "Topic|TemporalConcept") ) then
157
+ "subjects"
158
+ else
159
+ "names"
160
+ return
161
+ if ( fn:matches($n, "Person|Organization|Place|Meeting|Family|Topic|TemporalConcept") ) then
162
+ let $label := ($r/bf:authorizedAccessPoint, $r/bf:label)[1]
163
+ let $label := fn:normalize-space(xs:string($label))
164
+ let $req1 := local:http-get($label, $scheme)
165
+ let $resource :=
166
+ if ($req1[1]/@status eq 302) then
167
+ let $authuri := xs:string($req1[1]/httpexpath:header[@name eq "X-URI"][1]/@value)
168
+ return local:generate-resource($r, $authuri)
169
+ else if (
170
+ $req1[1]/@status ne 302 and
171
+ fn:ends-with($label, ".")
172
+ ) then
173
+ let $l := fn:substring($label, 1, fn:string-length($label)-1)
174
+ let $req2 := local:http-get($l, $scheme)
175
+ return
176
+ if ($req2[1]/@status eq 302) then
177
+ let $authuri := xs:string($req2[1]/httpexpath:header[@name eq "X-URI"][1]/@value)
178
+ return local:generate-resource($r, $authuri)
179
+ else
180
+ (: There was no match or some other message, keep moving :)
181
+ $r
182
+ else
183
+ $r
184
+ return $resource
185
+
186
+ else
187
+ $r
188
+
189
+ return <rdf:RDF>{$resources}</rdf:RDF>
190
+ };
191
+ let $usebnodes:= if ($usebnodes="") then "false" else $usebnodes
192
+ let $marcxml :=
193
+ if ( fn:starts-with($marcxmluri, "http://" ) or fn:starts-with($marcxmluri, "https://" ) ) then
194
+ let $http-response := http:get-node($marcxmluri)
195
+ return $http-response[2]
196
+ else
197
+ let $raw-data :=
198
+ if ( fn:starts-with($marcxmluri, "raw:" ) ) then
199
+ fn:substring($marcxmluri, 5)
200
+ else
201
+ file:read-text($marcxmluri)
202
+ let $mxml := parsexml:parse(
203
+ $raw-data,
204
+ <parseoptions:options />
205
+ )
206
+ return $mxml
207
+ let $marcxml := $marcxml//marcxml:record
208
+
209
+ let $resources :=
210
+ (:for $r in $marcxml:)
211
+ for $r in $marcxml[@type="Bibliographic" or fn:not(@type)]
212
+ let $controlnum := xs:string($r/marcxml:controlfield[@tag eq "001"][1])
213
+ let $holds:=
214
+ for $hold in $marcxml[fn:string(marcxml:controlfield[@tag="004"])=$controlnum]
215
+ return $hold
216
+
217
+ let $httpuri := fn:concat($baseuri , $controlnum)
218
+ let $recordset:= element marcxml:collection{$r,$holds}
219
+ let $bibframe := marcbib2bibframe:marcbib2bibframe($recordset,$httpuri)
220
+ return $bibframe/child::node()[fn:name()]
221
+
222
+ let $rdfxml-raw :=
223
+ element rdf:RDF {
224
+ $resources
225
+ }
226
+
227
+ let $rdfxml :=
228
+ if ( $serialization ne "rdfxml-raw" ) then
229
+ let $flatrdfxml := RDFXMLnested2flat:RDFXMLnested2flat($rdfxml-raw, $baseuri, $usebnodes)
230
+ return
231
+ if ($resolveLabelsWithID eq "true") then
232
+ local:resolve-labels($flatrdfxml)
233
+ else
234
+ $flatrdfxml
235
+ else
236
+ $rdfxml-raw
237
+
238
+ let $response :=
239
+ if ($serialization eq "ntriples") then
240
+ rdfxml2nt:rdfxml2ntriples($rdfxml)
241
+ else if ($serialization eq "json") then
242
+ rdfxml2json:rdfxml2json($rdfxml)
243
+ else if ($serialization eq "exhibitJSON") then
244
+ bfRDFXML2exhibitJSON:bfRDFXML2exhibitJSON($rdfxml, $baseuri)
245
+ else
246
+ $rdfxml
247
+
248
+ return $response
249
+
@@ -0,0 +1,362 @@
1
+ xquery version "3.0";
2
+
3
+ (:
4
+ : Module Name: MARC/XML BIB 2 BIBFRAME RDF using Saxon
5
+ :
6
+ : Module Version: 1.0
7
+ :
8
+ : Date: 2012 December 03
9
+ :
10
+ : Copyright: Public Domain
11
+ :
12
+ : Proprietary XQuery Extensions Used: Zorba (expath)
13
+ :
14
+ : Xquery Specification: January 2007
15
+ :
16
+ : Module Overview: Transforms MARC/XML Bibliographic records
17
+ : to RDF conforming to the BIBFRAME model. Outputs RDF/XML,
18
+ : N-triples, or JSON.
19
+
20
+ : adding holdings capability; allow <marcxml:collection> with multiple records,some holdigns, related to bibs on 004
21
+ :
22
+ : Run: zorba -i -q file:///location/of/zorba.xqy -e marcxmluri:="http://location/of/marcxml.xml" -e serialization:="rdfxml" -e baseuri:="http://your-base-uri/"
23
+ : Run: zorba -i -q file:///location/of/zorba.xqy -e marcxmluri:="../location/of/marcxml.xml" -e serialization:="rdfxml" -e baseuri:="http://your-base-uri/"
24
+ :)
25
+
26
+ (:~
27
+ : Transforms MARC/XML Bibliographic records
28
+ : to RDF conforming to the BIBFRAME model. Outputs RDF/XML,
29
+ : N-triples, or JSON.
30
+ :
31
+ : @author Nate Trail (ntra@loc.gov)
32
+ : @author Kevin Ford (kefo@loc.gov)
33
+ : @since December 17, 2014
34
+ : @version 1.0
35
+ :)
36
+
37
+ (: IMPORTED MODULES :)
38
+ import module namespace http = "http://zorba.io/modules/http-client";
39
+ import module namespace file = "http://expath.org/ns/file";
40
+ import module namespace parsexml = "http://zorba.io/modules/xml";
41
+ import schema namespace parseoptions = "http://zorba.io/modules/xml-options";
42
+
43
+ import module namespace marcbib2bibframe = "info:lc/id-modules/marcbib2bibframe#" at "../modules/module.MARCXMLBIB-2-BIBFRAME.xqy";
44
+ import module namespace rdfxml2nt = "info:lc/id-modules/rdfxml2nt#" at "../modules/module.RDFXML-2-Ntriples.xqy";
45
+ import module namespace rdfxml2json = "info:lc/id-modules/rdfxml2json#" at "../modules/module.RDFXML-2-JSON.xqy";
46
+ import module namespace bfRDFXML2exhibitJSON = "info:lc/bf-modules/bfRDFXML2exhibitJSON#" at "../modules/module.RDFXML-2-ExhibitJSON.xqy";
47
+ import module namespace RDFXMLnested2flat = "info:lc/bf-modules/RDFXMLnested2flat#" at "../modules/module.RDFXMLnested-2-flat.xqy";
48
+
49
+ (: NAMESPACES :)
50
+ declare namespace marcxml = "http://www.loc.gov/MARC21/slim";
51
+ declare namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
52
+ declare namespace rdfs = "http://www.w3.org/2000/01/rdf-schema#";
53
+
54
+ declare namespace bf = "http://bibframe.org/vocab/";
55
+ declare namespace madsrdf = "http://www.loc.gov/mads/rdf/v1#";
56
+ declare namespace relators = "http://id.loc.gov/vocabulary/relators/";
57
+ declare namespace identifiers = "http://id.loc.gov/vocabulary/identifiers/";
58
+ declare namespace notes = "http://id.loc.gov/vocabulary/notes/";
59
+
60
+ declare namespace an = "http://zorba.io/annotations";
61
+ declare namespace httpexpath = "http://expath.org/ns/http-client";
62
+ declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
63
+
64
+ declare namespace log = "info:lc/marc2bibframe/logging#";
65
+ declare namespace err = "http://www.w3.org/2005/xqt-errors";
66
+ declare namespace zerror = "http://zorba.io/errors";
67
+
68
+ (:~
69
+ : This variable is for the base uri for your Authorites/Concepts.
70
+ : It is the base URI for the rdf:about attribute.
71
+ :
72
+ :)
73
+ declare variable $baseuri as xs:string external := "http://example.org/";
74
+
75
+ (:~
76
+ : This variable determines whether bnodes should identify resources instead of
77
+ : http URIs, except for the "main" Work derived from each MARC record. At this time,
78
+ : the "main" Work must be identified by HTTP URI (using the $baseuri variable
79
+ : above).
80
+ :
81
+ :)
82
+ declare variable $usebnodes as xs:string external := "false";
83
+
84
+ (:~
85
+ : This variable is for the MARCXML location - externally defined.
86
+ :)
87
+ declare variable $marcxmluri as xs:string external;
88
+
89
+ (:~
90
+ : This variable is for desired serialzation. Expected values are: rdfxml (default), rdfxml-raw, ntriples, json, exhibitJSON, log
91
+ :)
92
+ declare variable $serialization as xs:string external := "rdfxml";
93
+
94
+ (:~
95
+ : This variable is for desired serialzation. Expected values are: rdfxml (default), rdfxml-raw, ntriples, json, exhibitJSON
96
+ :)
97
+ declare variable $resolveLabelsWithID as xs:string external := "false";
98
+
99
+ (:~
100
+ : If set to "true" will write log file to directory.
101
+ :)
102
+ declare variable $writelog as xs:string external := "false";
103
+
104
+ (:~
105
+ : Directory for log files. MUST end with a slash.
106
+ :)
107
+ declare variable $logdir as xs:string external := "";
108
+
109
+ (:~
110
+ Performs an http get but does not follow redirects
111
+
112
+ $l as xs:string is the label
113
+ $scheme as xs:string is the scheme
114
+ :)
115
+ declare %an:sequential function local:http-get(
116
+ $label as xs:string,
117
+ $scheme as xs:string
118
+ )
119
+ {
120
+ let $l := fn:encode-for-uri($label)
121
+ (:
122
+ let $request :=
123
+ httpexpath:send-request(
124
+ <httpexpath:request
125
+ method="GET"
126
+ href="http://id.loc.gov/authorities/{$scheme}/label/{$l}"
127
+ follow-redirect="false"/>
128
+ )
129
+ :)
130
+ let $options := fn:concat('{
131
+ "method": "GET",
132
+ "href": "http://id.loc.gov/authorities/', $scheme, '/label/', $l , '",
133
+ "options":
134
+ {
135
+ "status-only": true,
136
+ "override-media-type": "text/plain",
137
+ "follow-redirect": false,
138
+ "timeout": 5,
139
+ "user-agent": "MARC2BIBFRAME"
140
+ }
141
+ }')
142
+ let $request := http:send-request(jn:parse-json($options))
143
+ return $request
144
+ };
145
+
146
+ (:~
147
+ Outputs a resource, replacing verbose hasAuthority property
148
+ with a simple rdf:resource pointer
149
+
150
+ $resource as element() is the resource
151
+ $authuri as xs:string is the authority URI
152
+ :)
153
+ declare %an:nondeterministic function local:generate-resource(
154
+ $r as element(),
155
+ $authuri as xs:string
156
+ )
157
+ {
158
+ element { fn:name($r) } {
159
+ $r/@*,
160
+ $r/*[fn:name() ne "bf:hasAuthority"],
161
+ element bf:hasAuthority {
162
+ attribute rdf:resource { $authuri }
163
+ }
164
+ }
165
+ };
166
+
167
+
168
+ (:~
169
+ Tries to resolve Labels to URIs
170
+
171
+ $resource as element() is the resource
172
+ $authuri as xs:string is the authority URI
173
+ :)
174
+ declare %an:sequential function local:resolve-labels(
175
+ $flatrdfxml as element(rdf:RDF)
176
+ )
177
+ {
178
+ let $resources :=
179
+ for $r in $flatrdfxml/*
180
+ let $n := fn:local-name($r)
181
+ let $scheme :=
182
+ if ( fn:matches($n, "Topic|TemporalConcept") ) then
183
+ "subjects"
184
+ else
185
+ "names"
186
+ return
187
+ if ( fn:matches($n, "Person|Organization|Place|Meeting|Family|Topic|TemporalConcept") ) then
188
+ let $label := ($r/bf:authorizedAccessPoint, $r/bf:label)[1]
189
+ let $label := fn:normalize-space(xs:string($label))
190
+ let $req1 := local:http-get($label, $scheme)
191
+ let $resource :=
192
+ if ($req1("status") eq 302) then
193
+ let $authuri := xs:string($req1("headers")("X-URI"))
194
+ return local:generate-resource($r, $authuri)
195
+ else if (
196
+ $req1("status") ne 302 and
197
+ fn:ends-with($label, ".")
198
+ ) then
199
+ let $l := fn:substring($label, 1, fn:string-length($label)-1)
200
+ let $req2 := local:http-get($l, $scheme)
201
+ return
202
+ if ($req2("status") eq 302) then
203
+ let $authuri := xs:string($req2("headers")("X-URI"))
204
+ return local:generate-resource($r, $authuri)
205
+ else
206
+ (: There was no match or some other message, keep moving :)
207
+ $r
208
+ else
209
+ $r
210
+ return $resource
211
+
212
+ else
213
+ $r
214
+
215
+ return <rdf:RDF>{$resources}</rdf:RDF>
216
+ };
217
+ let $usebnodes:= if ($usebnodes="") then "false" else $usebnodes
218
+ let $startDT := fn:current-dateTime()
219
+ let $logfilename := fn:replace(fn:substring-before(xs:string($startDT), "."), "-|:", "")
220
+ let $logfilename := fn:concat($logdir, $logfilename, '.log.xml')
221
+
222
+ let $marcxml :=
223
+ if ( fn:starts-with($marcxmluri, "http://" ) or fn:starts-with($marcxmluri, "https://" ) ) then
224
+ let $json := http:get($marcxmluri)
225
+ return parsexml:parse($json("body")("content"), <parseoptions:options/>)
226
+ else
227
+ let $raw-data :=
228
+ if ( fn:starts-with($marcxmluri, "raw:" ) ) then
229
+ fn:substring($marcxmluri, 5)
230
+ else
231
+ file:read-text($marcxmluri)
232
+ let $mxml := parsexml:parse(
233
+ $raw-data,
234
+ <parseoptions:options />
235
+ )
236
+ return $mxml
237
+ let $marcxml := $marcxml//marcxml:record
238
+
239
+
240
+
241
+
242
+
243
+ let $result :=
244
+ (:for $r in $marcxml:)
245
+ for $r in $marcxml[@type="Bibliographic" or fn:not(@type)]
246
+ let $controlnum := xs:string($r/marcxml:controlfield[@tag eq "001"][1])
247
+ let $holds:=
248
+ for $hold in $marcxml[fn:string(marcxml:controlfield[@tag="004"])=$controlnum]
249
+ return $hold
250
+
251
+ let $httpuri := fn:concat($baseuri , $controlnum)
252
+ let $recordset:= element marcxml:collection{$r,$holds}
253
+ let $r :=
254
+ try {
255
+ let $rdf := marcbib2bibframe:marcbib2bibframe($recordset,$httpuri)
256
+ let $o := $rdf/child::node()[fn:name()]
257
+ let $logmsg :=
258
+ element log:success {
259
+ attribute uri {$httpuri},
260
+ attribute datetime { fn:current-dateTime() }
261
+ }
262
+ return
263
+ element result {
264
+ element logmsg {$logmsg},
265
+ element rdf {$o}
266
+ }
267
+ } catch * {
268
+ (: Could get entire stack trace from Zorba, but omitting for now. :)
269
+ let $stack1 := $zerror:stack-trace
270
+ let $logmsg :=
271
+ element log:error {
272
+ attribute uri {$httpuri},
273
+ attribute datetime { fn:current-dateTime() },
274
+ element log:error-details {
275
+ element log:error-xcode { xs:string($err:code) },
276
+ element log:error-description { xs:string($err:description) },
277
+ element log:error-file { xs:string($err:module) },
278
+ element log:error-line { xs:string($err:line-number) },
279
+ element log:error-column { xs:string($err:column-number) }
280
+ (: element log:error-stack { $stack1 } :)
281
+ },
282
+ element log:offending-record {
283
+ $r
284
+ }
285
+ }
286
+ return
287
+ element result {
288
+ element logmsg {$logmsg}
289
+ }
290
+ }
291
+ return
292
+ $r
293
+
294
+ let $rdfxml-raw :=
295
+ element rdf:RDF {
296
+ $result//rdf/child::node()[fn:name()]
297
+ }
298
+
299
+ let $rdfxml :=
300
+ if ( $serialization ne "rdfxml-raw" ) then
301
+ let $flatrdfxml := RDFXMLnested2flat:RDFXMLnested2flat($rdfxml-raw, $baseuri, $usebnodes)
302
+ return
303
+ if ($resolveLabelsWithID eq "true") then
304
+ local:resolve-labels($flatrdfxml)
305
+ else
306
+ $flatrdfxml
307
+ else
308
+ $rdfxml-raw
309
+
310
+ let $endDT := fn:current-dateTime()
311
+ let $log :=
312
+ element log:log {
313
+ attribute engine {"MarkLogic"},
314
+ attribute start {$startDT},
315
+ attribute end {$endDT},
316
+ attribute source {$marcxmluri},
317
+ attribute total-submitted { fn:count($marcxml) },
318
+ attribute total-success { fn:count($marcxml) - fn:count($result//logmsg/log:error) },
319
+ attribute total-error { fn:count($result//logmsg/log:error) },
320
+ $result//logmsg/log:*
321
+ }
322
+
323
+ let $logwritten :=
324
+ if ($writelog eq "true") then
325
+ file:write-text($logfilename, serialize($log,
326
+ <output:serialization-parameters>
327
+ <output:indent value="yes"/>
328
+ <output:method value="xml"/>
329
+ <output:omit-xml-declaration value="no"/>
330
+ </output:serialization-parameters>)
331
+ )
332
+ else
333
+ ()
334
+
335
+ (:
336
+ For now, not injecting notice about an error into the JSON outputs.
337
+ There are a couple of ways to do it (one is a hack, the other is the right way)
338
+ but 1) will it break anything and 2) is there a need?
339
+ :)
340
+ let $response :=
341
+ if ($serialization eq "ntriples") then
342
+ if (fn:count($result//logmsg/log:error) > 0) then
343
+ fn:concat("# Errors encountered. View 'log' for details.", fn:codepoints-to-string(10), rdfxml2nt:rdfxml2ntriples($rdfxml))
344
+ else
345
+ rdfxml2nt:rdfxml2ntriples($rdfxml)
346
+ else if ($serialization eq "json") then
347
+ rdfxml2json:rdfxml2json($rdfxml)
348
+ else if ($serialization eq "exhibitJSON") then
349
+ bfRDFXML2exhibitJSON:bfRDFXML2exhibitJSON($rdfxml, $baseuri)
350
+ else if ($serialization eq "log") then
351
+ $log
352
+ else
353
+ if (fn:count($result//logmsg/log:error) > 0) then
354
+ element rdf:RDF {
355
+ comment {"Errors encountered. View 'log' for details."},
356
+ $rdfxml/*
357
+ }
358
+ else
359
+ $rdfxml
360
+
361
+ return $response
362
+