1
- xquery version "1.0" ;
1
+ xquery version "1.0-ml " ;
2
2
3
3
(:
4
4
: Module Name: MARC/XML BIB 2 BIBFRAME RDF using MarkLogic
@@ -49,6 +49,9 @@ declare namespace relators = "http://id.loc.gov/vocabulary/relators/";
49
49
declare namespace identifiers = "http://id.loc.gov/vocabulary/identifiers/" ;
50
50
declare namespace notes = "http://id.loc.gov/vocabulary/notes/" ;
51
51
52
+ declare namespace log = "info:lc/marc2bibframe/logging#" ;
53
+ declare namespace mlerror = "http://marklogic.com/xdmp/error" ;
54
+
52
55
declare option xdmp:output "indent-untyped=yes" ;
53
56
54
57
(:~
@@ -64,10 +67,24 @@ declare variable $baseuri as xs:string := xdmp:get-request-field("baseuri","http
64
67
declare variable $marcxmluri as xs:string := xdmp:get-request-field ("marcxmluri" ,"" );
65
68
66
69
(:~
67
- : This variable is for desired serialzation. Expected values are: rdfxml (default), rdfxml-raw, ntriples, json, exhibitJSON
70
+ : This variable is for desired serialzation. Expected values are: rdfxml (default), rdfxml-raw, ntriples, json, exhibitJSON, log
68
71
:)
69
72
declare variable $serialization as xs:string := xdmp:get-request-field ("serialization" ,"rdfxml" );
70
73
74
+ (:~
75
+ : If set to "true" will write log file to directory.
76
+ :)
77
+ declare variable $writelog as xs:string := xdmp:get-request-field ("writelog" ,"false" );
78
+
79
+ (:~
80
+ : Directory for log files. MUST end with a slash.
81
+ :)
82
+ declare variable $logdir as xs:string := xdmp:get-request-field ("logdir" ,"" );
83
+
84
+ let $startDT := fn:current-dateTime ()
85
+ let $logfilename := fn:replace (fn:substring-before (xs:string ($startDT), "." ), "-|:" , "" )
86
+ let $logfilename := fn:concat ($logdir, $logfilename, '.log.xml' )
87
+
71
88
let $marcxml :=
72
89
xdmp:document-get (
73
90
$marcxmluri,
@@ -78,33 +95,124 @@ let $marcxml :=
78
95
79
96
let $marcxml := $marcxml//marcxml:record
80
97
81
- let $resources :=
98
+ let $result :=
82
99
for $r in $marcxml
83
100
let $controlnum := xs:string ($r/marcxml:controlfield[@tag eq "001" ][1 ])
84
101
let $httpuri := fn:concat ($baseuri , $controlnum)
85
- let $bibframe := marcbib2bibframe:marcbib2bibframe ($r,$httpuri)
86
- return $bibframe/child::node ()[fn:name ()]
87
-
102
+ let $r :=
103
+ try {
104
+ let $rdf := marcbib2bibframe:marcbib2bibframe ($r,$httpuri)
105
+ let $o := $rdf/child::node ()[fn:name ()]
106
+ let $logmsg :=
107
+ element log:success {
108
+ attribute uri {$httpuri},
109
+ attribute datetime { fn:current-dateTime () }
110
+ }
111
+ return
112
+ element result {
113
+ element logmsg {$logmsg},
114
+ element rdf {$o}
115
+ }
116
+ } catch ($e) {
117
+ (: ML provides the full stack, but for brevity only take the spawning error. :)
118
+ let $stack1 := $e/mlerror:stack/mlerror:frame[1 ]
119
+ let $vars :=
120
+ for $v in $stack1/mlerror:variables/mlerror:variable
121
+ return
122
+ element log:error-variable {
123
+ element log:error-name { xs:string ($v/mlerror:name) },
124
+ element log:error-value { xs:string ($v/mlerror:value ) }
125
+ }
126
+ let $logmsg :=
127
+ element log:error {
128
+ attribute uri {$httpuri},
129
+ attribute datetime { fn:current-dateTime () },
130
+ element log:error-details {
131
+ (: ML appears to be the actual err:* code in mlerror:name :)
132
+ element log:error-enginecode { xs:string ($e/mlerror:code) },
133
+ element log:error-xcode { xs:string ($e/mlerror:name) },
134
+ element log:error-msg { xs:string ($e/mlerror:message) },
135
+ element log:error-description { xs:string ($e/mlerror:format-string) },
136
+ element log:error-expression { xs:string ($e/mlerror:expr) },
137
+ element log:error-file { xs:string ($stack1/mlerror:uri) },
138
+ element log:error-line { xs:string ($stack1/mlerror:line) },
139
+ element log:error-column { xs:string ($stack1/mlerror:column) },
140
+ element log:error-operation { xs:string ($stack1/mlerror:operation) }
141
+ },
142
+ element log:offending-record {
143
+ $r
144
+ }
145
+ }
146
+ return
147
+ element result {
148
+ element logmsg {$logmsg}
149
+ }
150
+ }
151
+ return
152
+ $r
153
+
88
154
let $rdfxml-raw :=
89
155
element rdf:RDF {
90
- $resources
156
+ $result//rdf/child:: node ()[ fn:name ()]
91
157
}
92
158
93
159
let $rdfxml :=
94
160
if ( $serialization ne "rdfxml-raw" ) then
95
161
RDFXMLnested2flat:RDFXMLnested2flat ($rdfxml-raw, $baseuri)
96
162
else
97
163
$rdfxml-raw
98
-
164
+
165
+ let $endDT := fn:current-dateTime ()
166
+ let $log :=
167
+ element log:log {
168
+ attribute engine {"MarkLogic" },
169
+ attribute start {$startDT},
170
+ attribute end {$endDT},
171
+ attribute source {$marcxmluri},
172
+ attribute total-submitted { fn:count ($marcxml) },
173
+ attribute total-success { fn:count ($marcxml) - fn:count ($result//logmsg/log:error) },
174
+ attribute total-error { fn:count ($result//logmsg/log:error) },
175
+ $result//logmsg/log:*
176
+ }
177
+
178
+ (: This might be a problem if run in a modules database. :)
179
+ let $logwritten :=
180
+ if ($writelog eq "true" ) then
181
+ xdmp:save ($logfilename, $log,
182
+ <options xmlns = "xdmp:save" >
183
+ <indent>yes</indent>
184
+ <method>xml</method>
185
+ <output-encoding>utf-8 </output-encoding>
186
+ </options>
187
+ )
188
+ else
189
+ ()
190
+
191
+ (:
192
+ For now, not injecting notice about an error into the JSON outputs.
193
+ There are a couple of ways to do it (one is a hack, the other is the right way)
194
+ but 1) will it break anything and 2) is there a need?
195
+ :)
99
196
let $response :=
100
197
if ($serialization eq "ntriples" ) then
101
- rdfxml2nt:rdfxml2ntriples ($rdfxml)
198
+ if (fn:count ($result//logmsg/log:error) > 0 ) then
199
+ fn:concat ("# Errors encountered. View 'log' for details." , fn:codepoints-to-string (10 ), rdfxml2nt:rdfxml2ntriples ($rdfxml))
200
+ else
201
+ rdfxml2nt:rdfxml2ntriples ($rdfxml)
102
202
else if ($serialization eq "json" ) then
103
203
rdfxml2json:rdfxml2json ($rdfxml)
104
204
else if ($serialization eq "exhibitJSON" ) then
105
205
bfRDFXML2exhibitJSON:bfRDFXML2exhibitJSON ($rdfxml, $baseuri)
206
+ else if ($serialization eq "log" ) then
207
+ $log
106
208
else
107
- $rdfxml
209
+ if (fn:count ($result//logmsg/log:error) > 0 ) then
210
+ element rdf:RDF {
211
+ comment {"Errors encountered. View 'log' for details." },
212
+ $rdfxml/*
213
+ }
214
+ else
215
+ $rdfxml
108
216
109
217
return $response
110
218
0 commit comments