Coverage report: /development/source/library/org/datagraph/spocq-shard/src/core/encoding/rdf-xml.lisp

KindCoveredAll%
expression110805 13.7
branch354 5.6
Key
Not instrumented
Conditionalized out
Executed
Not executed
 
Both branches taken
One branch taken
Neither branch taken
1
 ;;; -*- Mode: lisp; Syntax: ansi-common-lisp; Base: 10; Package: org.datagraph.spocq.implementation; -*-
2
 
3
 (in-package :org.datagraph.spocq.implementation)
4
 
5
 ;;; rdf+xml serializer
6
 ;;; http://www.w3.org/TR/rdf-sparql-XMLres/
7
 
8
 ;;; no reading
9
 
10
 (defparameter *rdf-iri-cache* nil)
11
 (defparameter *namespace-prefix-count* 0)
12
 
13
 
14
 ;;; solution field writing - when as rdf, require just s-p-o
15
 
16
 (defgeneric write-rdf+xml (results stream)
17
   (:documentation "Encode the result field to the stream as rdf+xml.
18
  If results are a list of lists, then the first element is a header, which specifies the variable names and
19
  the remaining entries aer solutions sets. if a variable is unbound, the solution element is etf:nil.
20
  Otherwise, the results can be a matrix, in which case the dimensionality is explicit.")
21
   
22
   (:method ((result symbol) (stream t))
23
     (spocq.e:request-error "RDF+XML result is not a graph: ~s." result)
24
     0)
25
   
26
   (:method ((results list-solution-field) (stream t))
27
     (write-rdf+xml (cons (list-solution-field-dimensions results)
28
                          (list-solution-field-solutions results))
29
                    stream))
30
   
31
   (:method ((results cons) (stream t))
32
     (let* ((dimensions (first results))
33
            (solutions (rest results))
34
            (index 0)
35
            (start (or (response-offset) 0))
36
            (end (response-end))
37
            (*rdf-iri-cache* (make-hash-table :test 'equal))
38
            (*namespace-prefix-count* 0)
39
            (previous-subject nil))
40
 
41
       (cond ((equal dimensions *construct-dimensions*)
42
              )
43
             ((= (length dimensions) (length *construct-dimensions*))
44
              ;; (log-warn "RDF+XML dimensions assumed: dimensions ~s." dimensions)
45
              ;;(setf dimensions *construct-dimensions*)
46
              )
47
             (t
48
              (spocq.e:request-error "RDF+XML result is not a graph: dimensions ~s." dimensions)
49
              (return-from write-rdf+xml 0)))
50
 
51
       (format stream
52
               "<?xml version='1.0' encoding='utf-8'?>
53
 <rdf:RDF
54
    xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
55
    xmlns:rdfs='http://www.w3.org/2000/01/rdf-schema#'
56
    xmlns:xsd='http://www.w3.org/2001/XMLSchema#'>
57
 ")
58
       (dolist (solution solutions)
59
         (when (>= index start)
60
           (when (and end (>= index end))
61
             (return))
62
           (destructuring-bind (subject predicate object) solution
63
             (when object
64
               (cond ((equalp previous-subject subject)
65
                      (format stream "~%      "))
66
                     (t (unless (= index start)
67
                          (format stream "</rdf:Description>"))
68
                        (encode-rdf-xml-description-subject subject stream)))
69
               (encode-rdf-xml-description-predicate-and-object predicate object stream)
70
               (setf previous-subject subject)
71
               (incf index)))))
72
       (unless (= index start)
73
         (format stream "</rdf:Description>"))
74
       (format stream "</rdf:RDF>~%")
75
       (incf-stat *statements-returned* index)))
76
 
77
   (:method ((results boolean-generator) (stream t))
78
     (spocq.e:request-error "attempt to encode a boolean result as rdf+xml")
79
     0)
80
   
81
   (:method ((results solution-generator) (stream t))
82
     (let* ((dimensions (solution-generator-dimensions results))
83
            (channel (solution-generator-channel results))
84
            (variable-count (length dimensions))
85
            (index 0)
86
            (start (or (response-offset) 0))
87
            (end (response-end))
88
            (*rdf-iri-cache* (make-hash-table :test 'equal))
89
            (*namespace-prefix-count* 0))
90
 
91
       (cond ((equal dimensions *construct-dimensions*)
92
              )
93
             ((and (= (length dimensions) 4)
94
                   (equal (subseq dimensions 0 3) *construct-dimensions*))
95
              ) ; ignore the graph
96
             ((= (length dimensions) (length *construct-dimensions*))
97
              (log-warn "RDF+XML dimensions assumed: dimensions ~s." dimensions)
98
              (setf dimensions *construct-dimensions*))
99
             (t
100
              (spocq.e:request-error "RDF+XML result is not a graph: dimensions ~s." dimensions)
101
              (return-from write-rdf+xml 0)))
102
 
103
       (format stream
104
                 "<?xml version='1.0' encoding='utf-8'?>
105
 <rdf:RDF
106
    xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
107
    xmlns:rdfs='http://www.w3.org/2000/01/rdf-schema#'
108
    xmlns:xsd='http://www.w3.org/2001/XMLSchema#'>
109
 ")
110
       (do-pages (page channel)
111
                 (if (and end (>= index end))
112
                   (return)
113
                   (if (>= (+ index (array-dimension page 0)) start)
114
                     (cond ((= variable-count (array-dimension page 1))
115
                            (write-sparql-results-field-rdf+xml page stream index start end))
116
                           (t
117
                            (log-warn "field width mismatch: ~s : ~s."
118
                                      dimensions (array-dimension page 1))
119
                            (incf index (array-dimension page 0))))
120
                     ; otherwise skip the entire page
121
                     (incf index (array-dimension page 0)))))
122
       (format stream "</rdf:RDF>~%")
123
       (incf-stat *statements-returned* index)))
124
 
125
   (:method ((result-field true-matrix-field) (stream t))
126
     (spocq.e:request-error "attempt to encode a boolean result as rdf+xml")
127
     0)
128
 
129
   (:method ((result-field false-matrix-field) (stream t))
130
     (spocq.e:request-error "attempt to encode a boolean result as rdf+xml")
131
     0)
132
 
133
   (:method ((result-field matrix-field) (stream t))
134
     (let ((term-deconstructor (repository-term-deconstructor *transaction*))
135
           (dimensions (solution-field-dimensions result-field))
136
           (base-width 3)
137
           (start (or (response-offset) 0))
138
           (end (response-end))
139
           (result-count 0))
140
       (cond ((equal dimensions *construct-dimensions*)
141
              )
142
             ((and (= (length dimensions) 4)
143
                   (equal (subseq dimensions 0 3) *construct-dimensions*))
144
              (setf base-width 4))
145
             (t
146
              (spocq.e:request-error "RDF+XML result is not a graph: dimensions ~s." dimensions)
147
              (return-from write-rdf+xml 0)))
148
 
149
       (with-input-fields (result-field)
150
         (let ((%source-data (cffi::null-pointer))
151
               (source-row 0))
152
           (setf (values %source-data source-row) (first-field-row result-field))
153
           (loop until (and end (>= result-count (the fixnum end)))
154
                 until (cffi:null-pointer-p %source-data)
155
                 do (progn
156
                      (trace-matrix "~& write-rdf+xml.next ~@{~a ~}" :source-row source-row)
157
                      (when (> (incf result-count) start)
158
                      (let* ((term-offset (* base-width source-row))
159
                             (subject-term-id (#.+matrix-accessor+ (the sb-sys:system-area-pointer %source-data)
160
                                               (the fixnum (* #.(cffi:foreign-type-size +matrix-element-type+) term-offset))))
161
                             (predicate-term-id (#.+matrix-accessor+ (the sb-sys:system-area-pointer %source-data)
162
                                               (the fixnum (* #.(cffi:foreign-type-size +matrix-element-type+) (+ term-offset 1)))))
163
                             (object-term-id (#.+matrix-accessor+ (the sb-sys:system-area-pointer %source-data)
164
                                              (the fixnum (* #.(cffi:foreign-type-size +matrix-element-type+) (+ term-offset 2))))))
165
                        (unless (or (= subject-term-id +null-term-id+)
166
                                    (= predicate-term-id +null-term-id+)
167
                                    (= object-term-id +null-term-id+))
168
                          (flet ((subject-term-aspect-encoder (term-type term-literal term-language-tag term-datatype)
169
                                   ;; encode the element start tag as either an about iri or a node id.
170
                                   (encode-rdf-xml-description-subject-aspects term-type term-literal term-language-tag term-datatype stream))
171
                                 (predicate-term-aspect-encoder (term-type term-literal term-language-tag term-datatype)
172
                                   ;; encode the predicated relation as either an iri or a node and
173
                                   ;; complete the element with the content
174
                                   (flet ((object-term-aspect-encoder (o-term-type o-term-literal o-term-language-tag o-term-datatype)
175
                                            (encode-rdf-xml-description-predicate-and-object-aspects term-type term-literal term-language-tag term-datatype
176
                                                                                                     o-term-type o-term-literal o-term-language-tag o-term-datatype
177
                                                                                                     stream)))
178
                                     (declare (dynamic-extent #'object-term-aspect-encoder))
179
                                     (funcall term-deconstructor #'object-term-aspect-encoder *transaction* object-term-id))))
180
                            (declare (dynamic-extent #'subject-term-aspect-encoder))
181
                            (declare (dynamic-extent #'predicate-term-aspect-encoder))
182
                            (write-string "  " stream)
183
                            (funcall term-deconstructor #'subject-term-aspect-encoder *transaction* subject-term-id)
184
                            (funcall term-deconstructor #'predicate-term-aspect-encoder *transaction* predicate-term-id)
185
                            (format stream "</rdf:Description>~%"))))
186
                      (setf (values %source-data source-row) (next-field-row result-field)))))
187
           (incf-stat *statements-returned* (- result-count start)))))))
188
 
189
 
190
 (defgeneric rdf+xml-iri-parts (iri)
191
   (:method ((iri spocq:iri))
192
     (rdf+xml-iri-parts (spocq:iri-lexical-form iri)))
193
   (:method ((iri puri:uri))
194
     (rdf+xml-iri-parts (iri-lexical-form iri)))
195
   (:method ((iri symbol))
196
     (rdf+xml-iri-parts (iri-lexical-form iri)))
197
   (:method ((iri string))
198
     (flet ((split-iri (literal)
199
              (let ((scheme (parse-uri-scheme literal)))
200
                (case scheme
201
                  ((:http :https)
202
                   (let ((split-position (position-if #'(lambda (c) (or (eql c #\#) (eql c #\/))) literal :from-end t)))
203
                     (unless split-position
204
                       (spocq.e:request-error "Invalid rdf iri: ~s" literal))
205
                     (incf split-position)
206
                     (values (subseq literal 0 split-position)
207
                             (subseq literal split-position))))
208
                  ((:|URN:UUID| :urn :uuid)
209
                   (let ((split-position (position #\: literal :from-end t)))
210
                     (unless split-position
211
                       (spocq.e:request-error "Invalid rdf iri: ~s" literal))
212
                     (incf split-position)
213
                     (values (subseq literal 0 split-position)
214
                             (subseq literal split-position))))
215
                  ((nil)
216
                   (spocq.e:request-error "Invalid rdf iri: ~s" literal))
217
                  (t
218
                   (let ((split-position (position-if #'(lambda (c) (or (eql c #\#) (eql c #\/))) literal :from-end nil)))
219
                     (unless split-position
220
                       (spocq.e:request-error "Invalid rdf iri: ~s" literal))
221
                     (incf split-position)
222
                     (values (subseq literal 0 split-position)
223
                             (subseq literal split-position)))))))                 
224
            (namespace-name-prefix (namespace-name)
225
              (or (gethash namespace-name *rdf-iri-cache*)
226
                  (setf (gethash namespace-name *rdf-iri-cache*)
227
                        (format nil "ns~d" (incf *namespace-prefix-count*))))))
228
       (let ((cached-aspects (gethash iri *rdf-iri-cache*)))
229
         (if cached-aspects
230
           (apply #'values cached-aspects)
231
           (multiple-value-bind (namespace-name local-part) (split-iri iri)
232
             (let* ((prefix (namespace-name-prefix namespace-name))
233
                    (aspects (list prefix namespace-name local-part)))
234
               (setf (gethash iri *rdf-iri-cache*) aspects)
235
               (values prefix namespace-name local-part))))))))
236
 ;;; (let ((*rdf-iri-cache*  (make-hash-table :test 'equal))) (rdf+xml-iri-parts "urn:dydra:accessToken"))
237
 ;;; (let ((*rdf-iri-cache*  (make-hash-table :test 'equal))) (rdf+xml-iri-parts "uuid:00000000-1111-2222-3333-444444444444"))
238
 
239
 
240
 (defun encode-rdf-xml-description-subject-aspects (term-type term-literal term-language-tag term-datatype stream)
241
   "Encode the description element start tag with an about or a node id attribute respective
242
  the subject term type"
243
   (declare (ignore term-language-tag term-datatype))
244
   
245
   (write-string "<rdf:Description " stream)
246
   (case term-type
247
     (:node (format stream "rdf:nodeID='~@[~a_~]" (blank-node-prefix))
248
            (stream-write-external-utf8-string-as-xml stream term-literal)
249
            (write-char #\' stream))
250
     (:uri (format stream "rdf:about='")
251
           (stream-write-external-utf8-string-as-xml stream term-literal)
252
            (write-char #\' stream))
253
     (t (spocq.e:request-error "Invalid subject term type: ~s" term-type)))
254
   (write-char #\> stream))
255
 
256
 
257
 (defun encode-rdf-xml-description-predicate-and-object-aspects (p-term-type p-term-literal p-term-language-tag p-term-datatype
258
                                                                 o-term-type o-term-literal o-term-language-tag o-term-datatype
259
                                                                 stream)
260
   "Encode the predicate/object element with a generic identifier and namespace binding, with
261
  attributes respective the object datatype and with the object term literal as content."
262
   (declare (ignore p-term-language-tag p-term-datatype))
263
   
264
   (case p-term-type
265
     (:uri )
266
     (t (spocq.e:request-error "Invalid predicate term type: ~s" p-term-type)))
267
   (with-term-string (p-term-literal-string p-term-literal)      ; do it here in order to avoid 1.0.46 compiler bug
268
     (multiple-value-bind (prefix namespace-name local-part)
269
                          (rdf+xml-iri-parts p-term-literal-string)
270
       
271
       (format stream "<~a:~a    xmlns:~a='~a' "
272
               prefix local-part prefix namespace-name)
273
       
274
       (ecase o-term-type
275
         (:none )
276
         (:node                            ; encode a blank node
277
          (format stream "rdf:nodeID='~@[~a_~]" (blank-node-prefix))
278
          (stream-write-external-utf8-string-as-xml stream o-term-literal)
279
          (write-string "'/>" stream))
280
         (:literal ; encode a typed or language-tagged literal
281
                   ; in the latter case, suppress any datatype
282
          (cond ((not (cffi:null-pointer-p o-term-language-tag))
283
                 (write-string "xml:lang='" stream)
284
                 (stream-write-external-utf8-string-as-xml stream o-term-language-tag)
285
                 (write-string "' " stream))
286
                ((and (not (cffi:null-pointer-p o-term-datatype))
287
                      (not (%string-equal o-term-datatype (|%http://www.w3.org/2001/XMLSchema#string|))))
288
                 (write-string "rdf:datatype='" stream)
289
                 (stream-write-external-utf8-string-as-xml stream o-term-datatype)
290
                 (write-string "' " stream)))
291
          (write-char #\> stream)
292
          (stream-write-external-utf8-string-as-xml stream o-term-literal)
293
          (format stream "</~a:~a>" prefix local-part))
294
         (:uri                             ; encode a uri
295
          (write-string "rdf:resource='" stream)
296
          (stream-write-external-utf8-string-as-xml stream o-term-literal)
297
          (write-string "'/>" stream))))))
298
 
299
 
300
 
301
 (defun write-sparql-results-field-rdf+xml (page stream &optional (index 0) (start 0) end)
302
   (let ((term-deconstructor (repository-term-deconstructor *transaction*)))
303
     (dotimes (page-index (array-dimension page 0))
304
       (when (>= index start)
305
         (when (and end (>= index end))
306
           (return))
307
         (let ((subject-term-id (aref page page-index 0))
308
               (predicate-term-id (aref page page-index 1))
309
               (object-term-id (aref page page-index 2)))
310
           (unless (or (= subject-term-id +null-term-id+)
311
                       (= predicate-term-id +null-term-id+)
312
                       (= object-term-id +null-term-id+))
313
             (flet ((subject-term-aspect-encoder (term-type term-literal term-language-tag term-datatype)
314
                      ;; encode the element start tag as either an about iri or a node id.
315
                      (encode-rdf-xml-description-subject-aspects term-type term-literal term-language-tag term-datatype stream))
316
                    (predicate-term-aspect-encoder (term-type term-literal term-language-tag term-datatype)
317
                      ;; encode the predicated relation as either an iri or a node and
318
                      ;; complete the element with the content
319
                      (flet ((object-term-aspect-encoder (o-term-type o-term-literal o-term-language-tag o-term-datatype)
320
                               (encode-rdf-xml-description-predicate-and-object-aspects term-type term-literal term-language-tag term-datatype
321
                                                                                        o-term-type o-term-literal o-term-language-tag o-term-datatype
322
                                                                                        stream)))
323
                        (declare (dynamic-extent #'object-term-aspect-encoder))
324
                        (funcall term-deconstructor #'object-term-aspect-encoder *transaction* object-term-id))))
325
               (declare (dynamic-extent #'subject-term-aspect-encoder))
326
               (declare (dynamic-extent #'predicate-term-aspect-encoder))
327
               (write-string "  " stream)
328
               (funcall term-deconstructor #'subject-term-aspect-encoder *transaction* subject-term-id)
329
               (funcall term-deconstructor #'predicate-term-aspect-encoder *transaction* predicate-term-id)
330
               (format stream "</rdf:Description>~%")))
331
           (incf index))))
332
     index))
333
 
334
 
335
 
336
 
337
 
338
 (defgeneric encode-rdf-xml-description-subject (subject-term stream)
339
   (:documentation
340
    "Encode the complete description element start tag with an about or a node id attribute respective
341
     the subject term type")
342
 
343
   (:method :before ((term t) stream)
344
     (format stream "~%  <rdf:Description "))
345
 
346
   (:method :after ((term t) stream)
347
     (write-char #\> stream))
348
 
349
   (:method ((object spocq:blank-node) stream)
350
     (format stream "rdf:nodeID='~@[~a_~]~a'" (blank-node-prefix) (spocq:blank-node-label object)))
351
 
352
   (:method ((object spocq:iri) stream)
353
     (format stream "rdf:about='~/format-xml-iri-namestring/'" (spocq:iri-lexical-form object)))
354
 
355
   (:method ((object symbol) stream)
356
     (let ((uri-namestring (symbol-uri-namestring object)))
357
       (cond (uri-namestring
358
              (format stream "rdf:about='~/format-xml-iri-namestring/'" uri-namestring))
359
             (t
360
              (error "RDF encoding error: invalid value: ~s." object))))))
361
 
362
 
363
 (defun encode-rdf-xml-description-predicate-and-object (predicate object stream)
364
   "Encode the predicate as the rdf element start with a generic identifier and namespace binding.
365
    Leave the start tag incomplete in order that the object can be encoded as additional attributes
366
    and/or content.
367
    Delegate the object envoding to encode-rdf-xml-object.
368
    Finally, close the predicate element."
369
 
370
   (multiple-value-bind (prefix namespace-name local-part)
371
                        (rdf+xml-iri-parts predicate)
372
     (format stream "<~a:~a xmlns:~a='~a' " ;; leave it open for the object to complete
373
             prefix local-part prefix namespace-name)
374
     (encode-rdf-xml-object object stream)
375
     (format stream "</~a:~a>" prefix local-part)))
376
 
377
 
378
 (defgeneric encode-rdf-xml-object (term stream)
379
   (:method ((object function) stream)
380
     (funcall object stream))
381
 
382
   (:method ((object null) (stream t))
383
     ;; just in case, leave the syntax intact
384
     (write-char #\> stream))
385
 
386
   (:method ((object spocq:blank-node) stream)
387
     (format stream "rdf:nodeID='~@[~a_~]~a'>" (blank-node-prefix) (spocq:blank-node-label object)))
388
     
389
   (:method ((object spocq:iri) stream)
390
     (format stream "><rdf:Description rdf:about='~/format-xml-iri-namestring/'/>"
391
             (spocq:iri-lexical-form object)))
392
 
393
   (:method ((object symbol) stream)
394
     (case object
395
       ((spocq.a:|true| spocq.a:|false|)
396
        (format stream "rdf:datatype='http://www.w3.org/2001/XMLSchema#boolean'>~a"
397
                (symbol-name object)))
398
       (t
399
        (let ((uri-namestring (symbol-uri-namestring object)))
400
          (format stream "><rdf:Description rdf:about='~/format-xml-iri-namestring/'/>"
401
                  uri-namestring)))))
402
 
403
   (:method ((object spocq:boolean) stream)
404
     (format stream "rdf:datatype='http://www.w3.org/2001/XMLSchema#boolean'>~a"
405
             (spocq:literal-lexical-form object)))
406
 
407
   (:method ((object spocq:date) stream)
408
     (format stream "rdf:datatype='http://www.w3.org/2001/XMLSchema#date'>~a"
409
             (term-lexical-form object)))
410
 
411
   (:method ((object spocq:date-time) stream)
412
     (format stream "rdf:datatype='http://www.w3.org/2001/XMLSchema#dateTime'>~a"
413
             (term-lexical-form object)))
414
 
415
   (:method ((object spocq:time) stream)
416
     (format stream "rdf:datatype='http://www.w3.org/2001/XMLSchema#time'>~a"
417
             (term-lexical-form object)))
418
 
419
   (:method ((object spocq:day-time-duration) stream)
420
     (format stream "rdf:datatype='http://www.w3.org/2001/XMLSchema#dayTimeDuration'>~a"
421
             (term-lexical-form object)))
422
 
423
   (:method ((object spocq:year-month-duration) stream)
424
     (format stream "rdf:datatype='http://www.w3.org/2001/XMLSchema#yearMonthDuration'>~a"
425
             (term-lexical-form object)))
426
 
427
   (:method ((object spocq:plain-literal) stream)
428
     (format stream "xml:lang='~a'>~/format-xml-character-data/"
429
             (spocq:plain-literal-language-tag object)
430
             (spocq:literal-lexical-form object)))
431
 
432
   (:method ((object string) stream)
433
     (format stream ">~/format-xml-character-data/"
434
             object))
435
 
436
   (:method ((object spocq:unbound-variable) stream)
437
     ;; just in case, leave the syntax intact
438
     (write-char #\> stream))
439
   
440
   (:method ((object spocq:atomic-typed-literal) stream)
441
     (format stream "rdf:datatype='~/format-xml-iri-namestring/'>~/format-xml-character-data/"
442
             (spocq:literal-datatype-uri object)
443
             (spocq:literal-lexical-form object)))
444
     
445
   (:method ((object spocq:unsupported-typed-literal) stream)
446
     (format stream "rdf:datatype='~/format-xml-iri-namestring/'>~/format-xml-character-data/"
447
             (spocq:unsupported-typed-literal-datatype-uri object)
448
             (spocq:literal-lexical-form object)))
449
 
450
   (:method ((object integer) stream)
451
     (format stream "rdf:datatype='~a'>~a"
452
             (if *encode-object-subtypes*
453
               (typecase object
454
                 ((signed-byte 16) "http://www.w3.org/2001/XMLSchema#short")
455
                 (t "http://www.w3.org/2001/XMLSchema#integer"))
456
               "http://www.w3.org/2001/XMLSchema#integer")
457
             object))
458
 
459
   (:method ((object double-float) stream)
460
    (if (or (eql object dsu.codecs:double-float-nan)
461
            (eql object dsu.codecs:double-float-positive-infinity)
462
            (eql object dsu.codecs:double-float-negative-infinity))
463
      (spocq.e:request-error "encoding error: invalid float value: ~a" object)
464
      (let ((*read-default-float-format* 'double-float))
465
        (format stream "rdf:datatype='http://www.w3.org/2001/XMLSchema#double'>~f" object))))
466
 
467
   (:method ((object single-float) stream)
468
    (if (or (eql object nan) (eql object +inf) (eql object -inf))
469
      (spocq.e:request-error "Invalid float value: ~a" object)
470
      (let ((*read-default-float-format* 'single-float))
471
        (format stream "rdf:datatype='http://www.w3.org/2001/XMLSchema#float'>~f" object))))
472
 
473
   (:method ((object rational) stream)
474
     (let ((*read-default-float-format* 'single-float))
475
       (format stream "rdf:datatype='http://www.w3.org/2001/XMLSchema#decimal'>~f"
476
               (float object 1.0s0)))))
477
 ;;;
478
 
479
 (:documentation (send-error-message send-response-message)
480
   "The content-type application/rdf+xml indicates a response message message is to be coded
481
  as xml. This applies to responses only and corresponds to sparql requests.")
482
 
483
 (defmethod send-response-message (operation (message-body t) (stream t) (content-type mime:application/rdf+xml))
484
   "Given a MESSAGE, and a STREAM with the application/rdf+xml CONTENT-TYPE, encode as an xml rdf document"
485
   (when *encoding-trace-output*
486
     (setf stream (make-broadcast-stream *encoding-trace-output* stream)))
487
   (let ((*package* *spocq-reader-package*))
488
     (write-rdf+xml message-body stream)))
489
 
490
 
491
 #|
492
 (defparameter *rdf+xml=test=field*
493
   (cons *construct-dimensions*
494
         `( (<http://example/1> <http://example/p1> "object string")
495
            (<http://example/1> <http://example/p2> <http://example/object-uri>)
496
            (<http://example/1> <http://example/p2> |rdf|:|type|)
497
            (<http://example/1> <http://example/p2> ,(spocq:make-plain-literal "plain string" "EN") )
498
            (<http://example/2> <http://example/numeric> 3)
499
            (<http://example/2> <http://example/numeric> 3.1s0)
500
            (<http://example/2> <http://example/numeric> 3.2d0)
501
            (<http://example/2> <http://example/numeric> 10/3)
502
            (<http://example/3> <http://example/temporal> ,(spocq:make-date :year 2001 :month 01 :day 02))
503
            (<http://example/3> <http://example/temporal> ,(spocq:make-date-time :year 2001 :month 01 :day 02
504
                                                                                  :second 03 :minute 04 
505
                                                                                  :hour 05))
506
            (<http://example/4> <http://example/boolean> ,spocq.a:|false|)
507
            (<http://example/4> <http://example/boolean> ,spocq.a:|true|)
508
            (<_:node> |rdf|:|type| |owl|:|Class|))))
509
 
510
 (write-rdf+xml *rdf+xml=test=field* *trace-output*)
511
 
512
 (with-open-file (stream "/tmp/test.rdf" :direction :output :if-exists :supersede :if-does-not-exist :create)
513
   (write-rdf+xml *rdf+xml=test=field* stream))
514
 |#