rdflib 2.2.9 → 2.2.10-4fa7e876
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/rdflib.min.js +6 -6
- package/dist/rdflib.min.js.map +1 -1
- package/esm/n3parser.js +1330 -1286
- package/esm/rdfxmlparser.js +429 -412
- package/esm/serialize.js +1 -1
- package/esm/serializer.js +849 -821
- package/esm/xsd.js +9 -14
- package/lib/convert.d.ts +2 -0
- package/lib/jsonldparser.d.ts +13 -0
- package/lib/jsonparser.d.ts +4 -0
- package/lib/log.d.ts +15 -0
- package/lib/n3parser.d.ts +62 -0
- package/lib/n3parser.js +1334 -1289
- package/lib/patch-parser.d.ts +3 -0
- package/lib/query-to-sparql.d.ts +1 -0
- package/lib/query.d.ts +27 -0
- package/lib/rdfaparser.d.ts +78 -0
- package/lib/rdfxmlparser.d.ts +60 -0
- package/lib/rdfxmlparser.js +430 -413
- package/lib/serialize.d.ts +1 -1
- package/lib/serialize.js +1 -1
- package/lib/serializer.d.ts +54 -0
- package/lib/serializer.js +851 -824
- package/lib/sparql-to-query.d.ts +6 -0
- package/lib/updates-via.d.ts +26 -0
- package/lib/utils-js.d.ts +50 -0
- package/lib/xsd-internal.d.ts +11 -0
- package/lib/xsd.d.ts +19 -0
- package/lib/xsd.js +8 -14
- package/package.json +18 -18
- package/src/n3parser.js +1114 -1110
- package/src/rdfxmlparser.js +22 -21
- package/src/serialize.ts +3 -3
- package/src/serializer.js +74 -62
- package/src/xsd.js +16 -14
package/esm/serializer.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
4
|
+
|
|
1
5
|
/* Serialization of RDF Graphs
|
|
2
6
|
**
|
|
3
7
|
** Tim Berners-Lee 2006
|
|
@@ -12,8 +16,24 @@ import * as Util from './utils-js';
|
|
|
12
16
|
import CanonicalDataFactory from './factories/canonical-data-factory';
|
|
13
17
|
import { createXSD } from './xsd';
|
|
14
18
|
import solidNs from 'solid-namespace';
|
|
15
|
-
export default
|
|
16
|
-
|
|
19
|
+
export default function createSerializer(store) {
|
|
20
|
+
return new Serializer(store);
|
|
21
|
+
}
|
|
22
|
+
;
|
|
23
|
+
export var Serializer = /*#__PURE__*/function () {
|
|
24
|
+
function Serializer(store) {
|
|
25
|
+
_classCallCheck(this, Serializer);
|
|
26
|
+
|
|
27
|
+
_defineProperty(this, "_notQNameChars", '\t\r\n !"#$%&\'()*.,+/;<=>?@[\\]^`{|}~');
|
|
28
|
+
|
|
29
|
+
_defineProperty(this, "_notNameChars", this._notQNameChars + ':');
|
|
30
|
+
|
|
31
|
+
_defineProperty(this, "validPrefix", new RegExp(/^[a-zA-Z][a-zA-Z0-9]*$/));
|
|
32
|
+
|
|
33
|
+
_defineProperty(this, "forbidden1", new RegExp(/[\\"\b\f\r\v\t\n\u0080-\uffff]/gm));
|
|
34
|
+
|
|
35
|
+
_defineProperty(this, "forbidden3", new RegExp(/[\\"\b\f\r\v\u0080-\uffff]/gm));
|
|
36
|
+
|
|
17
37
|
this.flags = '';
|
|
18
38
|
this.base = null;
|
|
19
39
|
this.prefixes = []; // suggested prefixes
|
|
@@ -45,1090 +65,1098 @@ export default (function () {
|
|
|
45
65
|
this.store = store;
|
|
46
66
|
this.rdfFactory = store.rdfFactory || CanonicalDataFactory;
|
|
47
67
|
this.xsd = createXSD(this.rdfFactory);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
__Serializer.prototype.setBase = function (base) {
|
|
51
|
-
this.base = base;
|
|
52
|
-
return this;
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
__Serializer.prototype.setFlags = function (flags) {
|
|
56
|
-
this.flags = flags || '';
|
|
57
|
-
return this;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
__Serializer.prototype.toStr = function (x) {
|
|
61
|
-
var s = x.toNT();
|
|
68
|
+
}
|
|
62
69
|
|
|
63
|
-
|
|
64
|
-
|
|
70
|
+
_createClass(Serializer, [{
|
|
71
|
+
key: "setBase",
|
|
72
|
+
value: function setBase(base) {
|
|
73
|
+
this.base = base;
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
}, {
|
|
77
|
+
key: "setFlags",
|
|
78
|
+
value: function setFlags(flags) {
|
|
79
|
+
this.flags = flags || '';
|
|
80
|
+
return this;
|
|
65
81
|
}
|
|
82
|
+
}, {
|
|
83
|
+
key: "toStr",
|
|
84
|
+
value: function toStr(x) {
|
|
85
|
+
var s = x.toNT();
|
|
66
86
|
|
|
67
|
-
|
|
68
|
-
|
|
87
|
+
if (x.termType === 'Graph') {
|
|
88
|
+
this.formulas[s] = x; // remember as reverse does not work
|
|
89
|
+
}
|
|
69
90
|
|
|
70
|
-
|
|
71
|
-
if (s[0] === '{') {
|
|
72
|
-
var x = this.formulas[s];
|
|
73
|
-
if (!x) console.log('No formula object for ' + s);
|
|
74
|
-
return x;
|
|
91
|
+
return s;
|
|
75
92
|
}
|
|
93
|
+
}, {
|
|
94
|
+
key: "fromStr",
|
|
95
|
+
value: function fromStr(s) {
|
|
96
|
+
if (s[0] === '{') {
|
|
97
|
+
var x = this.formulas[s];
|
|
98
|
+
if (!x) console.log('No formula object for ' + s);
|
|
99
|
+
return x;
|
|
100
|
+
}
|
|
76
101
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
102
|
+
return this.store.fromNT(s);
|
|
103
|
+
}
|
|
104
|
+
/* Accumulate Namespaces
|
|
105
|
+
**
|
|
106
|
+
** These are only hints. If two overlap, only one gets used
|
|
107
|
+
** There is therefore no guarantee in general.
|
|
108
|
+
*/
|
|
85
109
|
|
|
86
|
-
|
|
87
|
-
|
|
110
|
+
}, {
|
|
111
|
+
key: "suggestPrefix",
|
|
112
|
+
value: function suggestPrefix(prefix, uri) {
|
|
113
|
+
if (prefix.slice(0, 7) === 'default') return; // Try to weed these out
|
|
88
114
|
|
|
89
|
-
|
|
115
|
+
if (prefix.slice(0, 2) === 'ns') return; // From others inferior algos
|
|
90
116
|
|
|
91
|
-
|
|
117
|
+
if (!prefix || !uri) return; // empty strings not suitable
|
|
92
118
|
|
|
93
|
-
|
|
119
|
+
if (prefix in this.namespaces || uri in this.prefixes) return; // already used
|
|
94
120
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
121
|
+
this.prefixes[uri] = prefix;
|
|
122
|
+
this.namespaces[prefix] = uri;
|
|
123
|
+
} // Takes a namespace -> prefix map
|
|
98
124
|
|
|
125
|
+
}, {
|
|
126
|
+
key: "suggestNamespaces",
|
|
127
|
+
value: function suggestNamespaces(namespaces) {
|
|
128
|
+
for (var px in namespaces) {
|
|
129
|
+
this.suggestPrefix(px, namespaces[px]);
|
|
130
|
+
}
|
|
99
131
|
|
|
100
|
-
|
|
101
|
-
for (var px in namespaces) {
|
|
102
|
-
this.suggestPrefix(px, namespaces[px]);
|
|
132
|
+
return this;
|
|
103
133
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
throw new Error('Serializer integity error 1: ' + p + ', ' + this.namespaces[p] + ', ' + this.prefixes[this.namespaces[p]] + '!');
|
|
134
|
+
}, {
|
|
135
|
+
key: "checkIntegrity",
|
|
136
|
+
value: function checkIntegrity() {
|
|
137
|
+
var p, ns;
|
|
138
|
+
|
|
139
|
+
for (p in this.namespaces) {
|
|
140
|
+
if (this.prefixes[this.namespaces[p]] !== p) {
|
|
141
|
+
throw new Error('Serializer integity error 1: ' + p + ', ' + this.namespaces[p] + ', ' + this.prefixes[this.namespaces[p]] + '!');
|
|
142
|
+
}
|
|
114
143
|
}
|
|
115
|
-
}
|
|
116
144
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
145
|
+
for (ns in this.prefixes) {
|
|
146
|
+
if (this.namespaces[this.prefixes[ns]] !== ns) {
|
|
147
|
+
throw new Error('Serializer integity error 2: ' + ns + ', ' + this.prefixs[ns] + ', ' + this.namespaces[this.prefixes[ns]] + '!');
|
|
148
|
+
}
|
|
120
149
|
}
|
|
121
|
-
}
|
|
122
|
-
}; // Make up an unused prefix for a random namespace
|
|
123
|
-
|
|
150
|
+
} // Make up an unused prefix for a random namespace
|
|
124
151
|
|
|
125
|
-
|
|
126
|
-
|
|
152
|
+
}, {
|
|
153
|
+
key: "makeUpPrefix",
|
|
154
|
+
value: function makeUpPrefix(uri) {
|
|
155
|
+
var p = uri;
|
|
127
156
|
|
|
128
|
-
|
|
129
|
-
|
|
157
|
+
function canUseMethod(pp) {
|
|
158
|
+
if (!this.validPrefix.test(pp)) return false; // bad format
|
|
130
159
|
|
|
131
|
-
|
|
160
|
+
if (pp === 'ns') return false; // boring
|
|
132
161
|
|
|
133
|
-
|
|
162
|
+
if (pp in this.namespaces) return false; // already used
|
|
134
163
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
164
|
+
this.prefixes[uri] = pp;
|
|
165
|
+
this.namespaces[pp] = uri;
|
|
166
|
+
return pp;
|
|
167
|
+
}
|
|
139
168
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
169
|
+
var canUse = canUseMethod.bind(this);
|
|
170
|
+
if ('#/'.indexOf(p[p.length - 1]) >= 0) p = p.slice(0, -1);
|
|
171
|
+
var slash = p.lastIndexOf('/');
|
|
172
|
+
if (slash >= 0) p = p.slice(slash + 1);
|
|
173
|
+
var i = 0;
|
|
145
174
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
175
|
+
while (i < p.length) {
|
|
176
|
+
if (this.prefixchars.indexOf(p[i])) {
|
|
177
|
+
i++;
|
|
178
|
+
} else {
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
151
181
|
}
|
|
152
|
-
}
|
|
153
182
|
|
|
154
|
-
|
|
155
|
-
|
|
183
|
+
p = p.slice(0, i);
|
|
184
|
+
if (p.length < 6 && canUse(p)) return p; // exact is best
|
|
156
185
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
186
|
+
if (canUse(p.slice(0, 3))) return p.slice(0, 3);
|
|
187
|
+
if (canUse(p.slice(0, 2))) return p.slice(0, 2);
|
|
188
|
+
if (canUse(p.slice(0, 4))) return p.slice(0, 4);
|
|
189
|
+
if (canUse(p.slice(0, 1))) return p.slice(0, 1);
|
|
190
|
+
if (canUse(p.slice(0, 5))) return p.slice(0, 5);
|
|
162
191
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
192
|
+
if (!this.validPrefix.test(p)) {
|
|
193
|
+
p = 'n'; // Otherwise the loop below may never termimnate
|
|
194
|
+
}
|
|
166
195
|
|
|
167
|
-
|
|
168
|
-
|
|
196
|
+
for (var j = 0;; j++) {
|
|
197
|
+
if (canUse(p.slice(0, 3) + j)) return p.slice(0, 3) + j;
|
|
198
|
+
}
|
|
169
199
|
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
for (var i = 0; i < sts.length; i++) {
|
|
185
|
-
var st = sts[i];
|
|
200
|
+
}, {
|
|
201
|
+
key: "rootSubjects",
|
|
202
|
+
value: function rootSubjects(sts) {
|
|
203
|
+
var incoming = {};
|
|
204
|
+
var subjects = {};
|
|
205
|
+
var allBnodes = {};
|
|
206
|
+
/* This scan is to find out which nodes will have to be the roots of trees
|
|
207
|
+
** in the serialized form. This will be any symbols, and any bnodes
|
|
208
|
+
** which hve more or less than one incoming arc, and any bnodes which have
|
|
209
|
+
** one incoming arc but it is an uninterrupted loop of such nodes back to itself.
|
|
210
|
+
** This should be kept linear time with repect to the number of statements.
|
|
211
|
+
** Note it does not use any indexing of the store.
|
|
212
|
+
*/
|
|
186
213
|
|
|
187
|
-
var
|
|
188
|
-
|
|
189
|
-
incoming[x].push(st.subject); // List of things which will cause this to be printed
|
|
190
|
-
};
|
|
214
|
+
for (var i = 0; i < sts.length; i++) {
|
|
215
|
+
var st = sts[i];
|
|
191
216
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
217
|
+
var checkMentions = function checkMentions(x) {
|
|
218
|
+
if (!incoming.hasOwnProperty(x)) incoming[x] = [];
|
|
219
|
+
incoming[x].push(st.subject); // List of things which will cause this to be printed
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
var st2 = [st.subject, st.predicate, st.object];
|
|
223
|
+
st2.map(function (y) {
|
|
224
|
+
if (y.termType === 'BlankNode') {
|
|
225
|
+
allBnodes[y.toNT()] = true;
|
|
226
|
+
} else if (y.termType === 'Collection') {
|
|
227
|
+
y.elements.forEach(function (z) {
|
|
228
|
+
checkMentions(z); // bnodes in collections important
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
checkMentions(sts[i].object);
|
|
233
|
+
var ss = subjects[this.toStr(st.subject)]; // Statements with this as subject
|
|
204
234
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
235
|
+
if (!ss) ss = [];
|
|
236
|
+
ss.push(st);
|
|
237
|
+
subjects[this.toStr(st.subject)] = ss; // Make hash. @@ too slow for formula?
|
|
238
|
+
}
|
|
209
239
|
|
|
210
|
-
|
|
240
|
+
var roots = [];
|
|
211
241
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
242
|
+
for (var xNT in subjects) {
|
|
243
|
+
if (!subjects.hasOwnProperty(xNT)) continue;
|
|
244
|
+
var y = this.fromStr(xNT);
|
|
215
245
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
246
|
+
if (y.termType !== 'BlankNode' || !incoming[y] || incoming[y].length !== 1) {
|
|
247
|
+
roots.push(y);
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
219
250
|
}
|
|
220
|
-
}
|
|
221
251
|
|
|
222
|
-
|
|
223
|
-
|
|
252
|
+
this.incoming = incoming; // Keep for serializing @@ Bug for nested formulas
|
|
253
|
+
// Now do the scan using existing roots
|
|
224
254
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
for (var k = 0; k < roots.length; k++) {
|
|
228
|
-
rootsHash[roots[k].toNT()] = true;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return {
|
|
232
|
-
'roots': roots,
|
|
233
|
-
'subjects': subjects,
|
|
234
|
-
'rootsHash': rootsHash,
|
|
235
|
-
'incoming': incoming
|
|
236
|
-
};
|
|
237
|
-
}; // //////////////////////////////////////////////////////
|
|
255
|
+
var rootsHash = {};
|
|
238
256
|
|
|
257
|
+
for (var k = 0; k < roots.length; k++) {
|
|
258
|
+
rootsHash[roots[k].toNT()] = true;
|
|
259
|
+
}
|
|
239
260
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
261
|
+
return {
|
|
262
|
+
'roots': roots,
|
|
263
|
+
'subjects': subjects,
|
|
264
|
+
'rootsHash': rootsHash,
|
|
265
|
+
'incoming': incoming
|
|
266
|
+
};
|
|
267
|
+
} // //////////////////////////////////////////////////////
|
|
243
268
|
|
|
244
|
-
|
|
245
|
-
|
|
269
|
+
}, {
|
|
270
|
+
key: "toN3",
|
|
271
|
+
value: function toN3(f) {
|
|
272
|
+
return this.statementsToN3(f.statements);
|
|
273
|
+
}
|
|
274
|
+
}, {
|
|
275
|
+
key: "explicitURI",
|
|
276
|
+
value: function explicitURI(uri) {
|
|
277
|
+
if (this.flags.indexOf('r') < 0 && this.base) {
|
|
278
|
+
uri = Uri.refTo(this.base, uri);
|
|
279
|
+
} else if (this.flags.indexOf('u') >= 0) {
|
|
280
|
+
// Unicode encoding NTriples style
|
|
281
|
+
uri = backslashUify(uri);
|
|
282
|
+
} else {
|
|
283
|
+
uri = hexify(uri);
|
|
284
|
+
}
|
|
246
285
|
|
|
247
|
-
|
|
248
|
-
if (this.flags.indexOf('r') < 0 && this.base) {
|
|
249
|
-
uri = Uri.refTo(this.base, uri);
|
|
250
|
-
} else if (this.flags.indexOf('u') >= 0) {
|
|
251
|
-
// Unicode encoding NTriples style
|
|
252
|
-
uri = backslashUify(uri);
|
|
253
|
-
} else {
|
|
254
|
-
uri = hexify(uri);
|
|
286
|
+
return '<' + uri + '>';
|
|
255
287
|
}
|
|
288
|
+
}, {
|
|
289
|
+
key: "statementsToNTriples",
|
|
290
|
+
value: function statementsToNTriples(sts) {
|
|
291
|
+
var sorted = sts.slice();
|
|
292
|
+
sorted.sort();
|
|
293
|
+
var str = '';
|
|
294
|
+
var rdfns = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
|
|
295
|
+
var self = this;
|
|
296
|
+
var kb = this.store;
|
|
297
|
+
var factory = this.rdfFactory;
|
|
298
|
+
|
|
299
|
+
var termToNT = function termToNT(x) {
|
|
300
|
+
if (x.termType !== 'Collection') {
|
|
301
|
+
return self.atomicTermToN3(x);
|
|
302
|
+
}
|
|
256
303
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
__Serializer.prototype.statementsToNTriples = function (sts) {
|
|
261
|
-
var sorted = sts.slice();
|
|
262
|
-
sorted.sort();
|
|
263
|
-
var str = '';
|
|
264
|
-
var rdfns = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
|
|
265
|
-
var self = this;
|
|
266
|
-
var kb = this.store;
|
|
267
|
-
var factory = this.rdfFactory;
|
|
268
|
-
|
|
269
|
-
var termToNT = function termToNT(x) {
|
|
270
|
-
if (x.termType !== 'Collection') {
|
|
271
|
-
return self.atomicTermToN3(x);
|
|
272
|
-
}
|
|
304
|
+
var list = x.elements;
|
|
305
|
+
var rest = kb.sym(rdfns + 'nill');
|
|
273
306
|
|
|
274
|
-
|
|
275
|
-
|
|
307
|
+
for (var i = list.length - 1; i >= 0; i--) {
|
|
308
|
+
var bnode = factory.blankNode();
|
|
309
|
+
str += termToNT(bnode) + ' ' + termToNT(kb.sym(rdfns + 'first')) + ' ' + termToNT(list[i]) + '.\n';
|
|
310
|
+
str += termToNT(bnode) + ' ' + termToNT(kb.sym(rdfns + 'rest')) + ' ' + termToNT(rest) + '.\n';
|
|
311
|
+
rest = bnode;
|
|
312
|
+
}
|
|
276
313
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
str += termToNT(bnode) + ' ' + termToNT(kb.sym(rdfns + 'first')) + ' ' + termToNT(list[i]) + '.\n';
|
|
280
|
-
str += termToNT(bnode) + ' ' + termToNT(kb.sym(rdfns + 'rest')) + ' ' + termToNT(rest) + '.\n';
|
|
281
|
-
rest = bnode;
|
|
282
|
-
}
|
|
314
|
+
return self.atomicTermToN3(rest);
|
|
315
|
+
};
|
|
283
316
|
|
|
284
|
-
|
|
285
|
-
|
|
317
|
+
for (var i = 0; i < sorted.length; i++) {
|
|
318
|
+
var st = sorted[i];
|
|
319
|
+
var s = '';
|
|
320
|
+
s += termToNT(st.subject) + ' ';
|
|
321
|
+
s += termToNT(st.predicate) + ' ';
|
|
322
|
+
s += termToNT(st.object) + ' ';
|
|
286
323
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
s += termToNT(st.predicate) + ' ';
|
|
292
|
-
s += termToNT(st.object) + ' ';
|
|
324
|
+
if (this.flags.indexOf('q') >= 0) {
|
|
325
|
+
// Do quads not nrtiples
|
|
326
|
+
s += termToNT(st.why) + ' ';
|
|
327
|
+
}
|
|
293
328
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
s += termToNT(st.why) + ' ';
|
|
329
|
+
s += '.\n';
|
|
330
|
+
str += s;
|
|
297
331
|
}
|
|
298
332
|
|
|
299
|
-
|
|
300
|
-
str += s;
|
|
333
|
+
return str;
|
|
301
334
|
}
|
|
335
|
+
}, {
|
|
336
|
+
key: "statementsToN3",
|
|
337
|
+
value: function statementsToN3(sts) {
|
|
338
|
+
var indent = 4;
|
|
339
|
+
var width = 80;
|
|
340
|
+
var kb = this.store; // A URI Map alows us to put the type statemnts at the top.
|
|
341
|
+
|
|
342
|
+
var uriMap = {
|
|
343
|
+
'http://www.w3.org/1999/02/22-rdf-syntax-ns#type': 'aaa:00'
|
|
344
|
+
};
|
|
302
345
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
var indent = 4;
|
|
308
|
-
var width = 80;
|
|
309
|
-
var kb = this.store; // A URI Map alows us to put the type statemnts at the top.
|
|
310
|
-
|
|
311
|
-
var uriMap = {
|
|
312
|
-
'http://www.w3.org/1999/02/22-rdf-syntax-ns#type': 'aaa:00'
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
var SPO = function SPO(x, y) {
|
|
316
|
-
// Do limited canonicalization of bnodes
|
|
317
|
-
return Util.heavyCompareSPO(x, y, kb, uriMap);
|
|
318
|
-
};
|
|
346
|
+
var SPO = function SPO(x, y) {
|
|
347
|
+
// Do limited canonicalization of bnodes
|
|
348
|
+
return Util.heavyCompareSPO(x, y, kb, uriMap);
|
|
349
|
+
};
|
|
319
350
|
|
|
320
|
-
|
|
351
|
+
sts.sort(SPO);
|
|
321
352
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
353
|
+
if (this.base && !this.defaultNamespace) {
|
|
354
|
+
this.defaultNamespace = this.base + '#';
|
|
355
|
+
}
|
|
325
356
|
|
|
326
|
-
|
|
357
|
+
var predMap = {};
|
|
327
358
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
359
|
+
if (this.flags.indexOf('s') < 0) {
|
|
360
|
+
predMap['http://www.w3.org/2002/07/owl#sameAs'] = '=';
|
|
361
|
+
}
|
|
331
362
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
363
|
+
if (this.flags.indexOf('t') < 0) {
|
|
364
|
+
predMap['http://www.w3.org/1999/02/22-rdf-syntax-ns#type'] = 'a';
|
|
365
|
+
}
|
|
335
366
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
367
|
+
if (this.flags.indexOf('i') < 0) {
|
|
368
|
+
predMap['http://www.w3.org/2000/10/swap/log#implies'] = '=>';
|
|
369
|
+
} // //////////////////////// Arrange the bits of text
|
|
339
370
|
|
|
340
371
|
|
|
341
|
-
|
|
342
|
-
|
|
372
|
+
var spaces = function spaces(n) {
|
|
373
|
+
var s = '';
|
|
343
374
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
375
|
+
for (var i = 0; i < n; i++) {
|
|
376
|
+
s += ' ';
|
|
377
|
+
}
|
|
347
378
|
|
|
348
|
-
|
|
349
|
-
|
|
379
|
+
return s;
|
|
380
|
+
};
|
|
350
381
|
|
|
351
|
-
|
|
352
|
-
|
|
382
|
+
var treeToLine = function treeToLine(tree) {
|
|
383
|
+
var str = '';
|
|
353
384
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
385
|
+
for (var i = 0; i < tree.length; i++) {
|
|
386
|
+
var branch = tree[i];
|
|
387
|
+
var s2 = typeof branch === 'string' ? branch : treeToLine(branch); // Note the space before the dot in case statement ends 123. which is in fact allowed but be conservative.
|
|
357
388
|
|
|
358
|
-
|
|
359
|
-
|
|
389
|
+
if (i !== 0) {
|
|
390
|
+
var ch = str.slice(-1) || ' ';
|
|
360
391
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
392
|
+
if (s2 === ',' || s2 === ';') {// no gap
|
|
393
|
+
} else if (s2 === '.' && !'0123456789.'.includes(ch)) {// no gap except after number
|
|
394
|
+
// no gap
|
|
395
|
+
} else {
|
|
396
|
+
str += ' '; // separate from previous token
|
|
397
|
+
}
|
|
366
398
|
}
|
|
367
|
-
}
|
|
368
399
|
|
|
369
|
-
|
|
370
|
-
|
|
400
|
+
str += s2;
|
|
401
|
+
}
|
|
371
402
|
|
|
372
|
-
|
|
373
|
-
|
|
403
|
+
return str;
|
|
404
|
+
}; // Convert a nested tree of lists and strings to a string
|
|
374
405
|
|
|
375
406
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
407
|
+
var treeToString = function treeToString(tree, level) {
|
|
408
|
+
var str = '';
|
|
409
|
+
var lastLength = 100000;
|
|
410
|
+
if (level === undefined) level = -1;
|
|
380
411
|
|
|
381
|
-
|
|
382
|
-
|
|
412
|
+
for (var i = 0; i < tree.length; i++) {
|
|
413
|
+
var branch = tree[i];
|
|
383
414
|
|
|
384
|
-
|
|
385
|
-
|
|
415
|
+
if (typeof branch !== 'string') {
|
|
416
|
+
var substr = treeToString(branch, level + 1);
|
|
386
417
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
418
|
+
if (substr.length < 10 * (width - indent * level) && substr.indexOf('"""') < 0) {
|
|
419
|
+
// Don't mess up multiline strings
|
|
420
|
+
var line = treeToLine(branch);
|
|
390
421
|
|
|
391
|
-
|
|
392
|
-
|
|
422
|
+
if (line.length < width - indent * level) {
|
|
423
|
+
branch = line; // Note! treat as string below
|
|
393
424
|
|
|
394
|
-
|
|
425
|
+
substr = '';
|
|
426
|
+
}
|
|
395
427
|
}
|
|
396
|
-
}
|
|
397
428
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
429
|
+
if (substr) lastLength = 10000;
|
|
430
|
+
str += substr;
|
|
431
|
+
}
|
|
401
432
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
433
|
+
if (typeof branch === 'string') {
|
|
434
|
+
if (branch.length === 1 && str.slice(-1) === '\n') {
|
|
435
|
+
if (',.;'.indexOf(branch) >= 0) {
|
|
436
|
+
str = str.slice(0, -1) + branch + '\n'; // slip punct'n on end
|
|
406
437
|
|
|
407
|
-
|
|
408
|
-
|
|
438
|
+
lastLength += 1;
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
409
441
|
}
|
|
410
|
-
}
|
|
411
442
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
443
|
+
if (lastLength < indent * level + 4 || // if new line not necessary
|
|
444
|
+
lastLength + branch.length + 1 < width && ';.'.indexOf(str[str.length - 2]) < 0) {
|
|
445
|
+
// or the string fits on last line
|
|
446
|
+
str = str.slice(0, -1) + ' ' + branch + '\n'; // then continue on this line
|
|
416
447
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
448
|
+
lastLength += branch.length + 1;
|
|
449
|
+
} else {
|
|
450
|
+
var _line = spaces(indent * level) + branch;
|
|
420
451
|
|
|
421
|
-
|
|
422
|
-
|
|
452
|
+
str += _line + '\n';
|
|
453
|
+
lastLength = _line.length;
|
|
423
454
|
|
|
424
|
-
|
|
425
|
-
|
|
455
|
+
if (level < 0) {
|
|
456
|
+
str += '\n'; // extra blank line
|
|
426
457
|
|
|
427
|
-
|
|
458
|
+
lastLength = 100000; // don't touch
|
|
459
|
+
}
|
|
428
460
|
}
|
|
429
461
|
}
|
|
430
462
|
}
|
|
431
|
-
}
|
|
432
463
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
464
|
+
return str;
|
|
465
|
+
}; // //////////////////////////////////////////// Structure for N3
|
|
466
|
+
// Convert a set of statements into a nested tree of lists and strings
|
|
467
|
+
|
|
436
468
|
|
|
469
|
+
function statementListToTreeMethod(statements) {
|
|
470
|
+
var stats = this.rootSubjects(statements);
|
|
471
|
+
var roots = stats.roots;
|
|
472
|
+
var results = [];
|
|
437
473
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
474
|
+
for (var i = 0; i < roots.length; i++) {
|
|
475
|
+
var root = roots[i];
|
|
476
|
+
results.push(subjectTree(root, stats));
|
|
477
|
+
}
|
|
442
478
|
|
|
443
|
-
|
|
444
|
-
var root = roots[i];
|
|
445
|
-
results.push(subjectTree(root, stats));
|
|
479
|
+
return results;
|
|
446
480
|
}
|
|
447
481
|
|
|
448
|
-
|
|
449
|
-
}
|
|
482
|
+
var statementListToTree = statementListToTreeMethod.bind(this); // The tree for a subject
|
|
450
483
|
|
|
451
|
-
|
|
484
|
+
function subjectTree(subject, stats) {
|
|
485
|
+
if (subject.termType === 'BlankNode' && !stats.incoming[subject]) {
|
|
486
|
+
return objectTree(subject, stats, true).concat(['.']); // Anonymous bnode subject
|
|
487
|
+
}
|
|
452
488
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
return objectTree(subject, stats, true).concat(['.']); // Anonymous bnode subject
|
|
456
|
-
}
|
|
489
|
+
return [termToN3(subject, stats)].concat([propertyTree(subject, stats)]).concat(['.']);
|
|
490
|
+
} // The property tree for a single subject or anonymous node
|
|
457
491
|
|
|
458
|
-
return [termToN3(subject, stats)].concat([propertyTree(subject, stats)]).concat(['.']);
|
|
459
|
-
} // The property tree for a single subject or anonymous node
|
|
460
492
|
|
|
493
|
+
function propertyTreeMethod(subject, stats) {
|
|
494
|
+
var results = [];
|
|
495
|
+
var lastPred = null;
|
|
496
|
+
var sts = stats.subjects[this.toStr(subject)] || []; // relevant statements
|
|
461
497
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
var sts = stats.subjects[this.toStr(subject)] || []; // relevant statements
|
|
498
|
+
if (typeof sts === 'undefined') {
|
|
499
|
+
throw new Error('Cant find statements for ' + subject);
|
|
500
|
+
}
|
|
466
501
|
|
|
467
|
-
|
|
468
|
-
throw new Error('Cant find statements for ' + subject);
|
|
469
|
-
}
|
|
502
|
+
var objects = [];
|
|
470
503
|
|
|
471
|
-
|
|
504
|
+
for (var i = 0; i < sts.length; i++) {
|
|
505
|
+
var st = sts[i];
|
|
472
506
|
|
|
473
|
-
|
|
474
|
-
|
|
507
|
+
if (st.predicate.uri === lastPred) {
|
|
508
|
+
objects.push(',');
|
|
509
|
+
} else {
|
|
510
|
+
if (lastPred) {
|
|
511
|
+
results = results.concat([objects]).concat([';']);
|
|
512
|
+
objects = [];
|
|
513
|
+
}
|
|
475
514
|
|
|
476
|
-
|
|
477
|
-
objects.push(',');
|
|
478
|
-
} else {
|
|
479
|
-
if (lastPred) {
|
|
480
|
-
results = results.concat([objects]).concat([';']);
|
|
481
|
-
objects = [];
|
|
515
|
+
results.push(predMap[st.predicate.uri] ? predMap[st.predicate.uri] : termToN3(st.predicate, stats));
|
|
482
516
|
}
|
|
483
517
|
|
|
484
|
-
|
|
518
|
+
lastPred = st.predicate.uri;
|
|
519
|
+
objects.push(objectTree(st.object, stats));
|
|
485
520
|
}
|
|
486
521
|
|
|
487
|
-
|
|
488
|
-
|
|
522
|
+
results = results.concat([objects]);
|
|
523
|
+
return results;
|
|
489
524
|
}
|
|
490
525
|
|
|
491
|
-
|
|
492
|
-
return results;
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
var propertyTree = propertyTreeMethod.bind(this);
|
|
526
|
+
var propertyTree = propertyTreeMethod.bind(this);
|
|
496
527
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
528
|
+
function objectTreeMethod(obj, stats, force) {
|
|
529
|
+
if (obj.termType === 'BlankNode' && (force || stats.rootsHash[obj.toNT()] === undefined)) {
|
|
530
|
+
// if not a root
|
|
531
|
+
if (stats.subjects[this.toStr(obj)]) {
|
|
532
|
+
return ['[', propertyTree(obj, stats), ']'];
|
|
533
|
+
} else {
|
|
534
|
+
return '[]';
|
|
535
|
+
}
|
|
504
536
|
}
|
|
505
|
-
}
|
|
506
537
|
|
|
507
|
-
|
|
508
|
-
|
|
538
|
+
return termToN3(obj, stats);
|
|
539
|
+
}
|
|
509
540
|
|
|
510
|
-
|
|
541
|
+
var objectTree = objectTreeMethod.bind(this);
|
|
511
542
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
543
|
+
function termToN3Method(expr, stats) {
|
|
544
|
+
//
|
|
545
|
+
var i, res;
|
|
515
546
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
547
|
+
switch (expr.termType) {
|
|
548
|
+
case 'Graph':
|
|
549
|
+
res = ['{'];
|
|
550
|
+
res = res.concat(statementListToTree(expr.statements));
|
|
551
|
+
return res.concat(['}']);
|
|
521
552
|
|
|
522
|
-
|
|
523
|
-
|
|
553
|
+
case 'Collection':
|
|
554
|
+
res = ['('];
|
|
524
555
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
556
|
+
for (i = 0; i < expr.elements.length; i++) {
|
|
557
|
+
res.push([objectTree(expr.elements[i], stats)]);
|
|
558
|
+
}
|
|
528
559
|
|
|
529
|
-
|
|
530
|
-
|
|
560
|
+
res.push(')');
|
|
561
|
+
return res;
|
|
531
562
|
|
|
532
|
-
|
|
533
|
-
|
|
563
|
+
default:
|
|
564
|
+
return this.atomicTermToN3(expr);
|
|
565
|
+
}
|
|
534
566
|
}
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
__Serializer.prototype.termToN3 = termToN3;
|
|
538
|
-
var termToN3 = termToN3Method.bind(this);
|
|
539
567
|
|
|
540
|
-
|
|
541
|
-
var
|
|
542
|
-
|
|
543
|
-
if (this.defaultNamespace) {
|
|
544
|
-
str += '@prefix : ' + this.explicitURI(this.defaultNamespace) + '.\n';
|
|
545
|
-
}
|
|
568
|
+
Serializer.prototype.termToN3 = termToN3;
|
|
569
|
+
var termToN3 = termToN3Method.bind(this);
|
|
546
570
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
if (!this.namespacesUsed[ns]) continue;
|
|
550
|
-
str += '@prefix ' + this.prefixes[ns] + ': ' + this.explicitURI(ns) + '.\n';
|
|
551
|
-
}
|
|
571
|
+
function prefixDirectivesMethod() {
|
|
572
|
+
var str = '';
|
|
552
573
|
|
|
553
|
-
|
|
554
|
-
|
|
574
|
+
if (this.defaultNamespace) {
|
|
575
|
+
str += '@prefix : ' + this.explicitURI(this.defaultNamespace) + '.\n';
|
|
576
|
+
}
|
|
555
577
|
|
|
556
|
-
|
|
578
|
+
for (var ns in this.prefixes) {
|
|
579
|
+
if (!this.prefixes.hasOwnProperty(ns)) continue;
|
|
580
|
+
if (!this.namespacesUsed[ns]) continue;
|
|
581
|
+
str += '@prefix ' + this.prefixes[ns] + ': ' + this.explicitURI(ns) + '.\n';
|
|
582
|
+
}
|
|
557
583
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
}; // //////////////////////////////////////////// Atomic Terms
|
|
561
|
-
// Deal with term level things and nesting with no bnode structure
|
|
584
|
+
return str + '\n';
|
|
585
|
+
}
|
|
562
586
|
|
|
587
|
+
var prefixDirectives = prefixDirectivesMethod.bind(this); // Body of statementsToN3:
|
|
563
588
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
return expr.toNT();
|
|
589
|
+
var tree = statementListToTree(sts);
|
|
590
|
+
return prefixDirectives() + treeToString(tree);
|
|
591
|
+
} // //////////////////////////////////////////// Atomic Terms
|
|
592
|
+
// Deal with term level things and nesting with no bnode structure
|
|
569
593
|
|
|
570
|
-
|
|
571
|
-
|
|
594
|
+
}, {
|
|
595
|
+
key: "atomicTermToN3",
|
|
596
|
+
value: function atomicTermToN3(expr, stats) {
|
|
597
|
+
switch (expr.termType) {
|
|
598
|
+
case 'BlankNode':
|
|
599
|
+
case 'Variable':
|
|
600
|
+
return expr.toNT();
|
|
572
601
|
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
} // var val = expr.value.toString() // should be a string already
|
|
602
|
+
case 'Literal':
|
|
603
|
+
var val = expr.value;
|
|
576
604
|
|
|
605
|
+
if (typeof val !== 'string') {
|
|
606
|
+
throw new TypeError('Value of RDF literal node must be a string');
|
|
607
|
+
} // var val = expr.value.toString() // should be a string already
|
|
577
608
|
|
|
578
|
-
if (expr.datatype && this.flags.indexOf('x') < 0) {
|
|
579
|
-
// Supress native numbers
|
|
580
|
-
switch (expr.datatype.uri) {
|
|
581
|
-
case 'http://www.w3.org/2001/XMLSchema#integer':
|
|
582
|
-
return val;
|
|
583
609
|
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
610
|
+
if (expr.datatype && this.flags.indexOf('x') < 0) {
|
|
611
|
+
// Supress native numbers
|
|
612
|
+
switch (expr.datatype.uri) {
|
|
613
|
+
case 'http://www.w3.org/2001/XMLSchema#integer':
|
|
614
|
+
return val;
|
|
588
615
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
var eNotation = val.toLowerCase().indexOf('e') > 0;
|
|
593
|
-
if (val.indexOf('.') < 0 && !eNotation) val += '.0';
|
|
594
|
-
if (!eNotation) val += 'e0';
|
|
616
|
+
case 'http://www.w3.org/2001/XMLSchema#decimal':
|
|
617
|
+
// In urtle must have dot
|
|
618
|
+
if (val.indexOf('.') < 0) val += '.0';
|
|
595
619
|
return val;
|
|
596
|
-
}
|
|
597
620
|
|
|
598
|
-
|
|
599
|
-
|
|
621
|
+
case 'http://www.w3.org/2001/XMLSchema#double':
|
|
622
|
+
{
|
|
623
|
+
// Must force use of 'e'
|
|
624
|
+
var eNotation = val.toLowerCase().indexOf('e') > 0;
|
|
625
|
+
if (val.indexOf('.') < 0 && !eNotation) val += '.0';
|
|
626
|
+
if (!eNotation) val += 'e0';
|
|
627
|
+
return val;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
case 'http://www.w3.org/2001/XMLSchema#boolean':
|
|
631
|
+
return expr.value === '1' ? 'true' : 'false';
|
|
632
|
+
}
|
|
600
633
|
}
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
var str = this.stringToN3(expr.value);
|
|
604
|
-
|
|
605
|
-
if (expr.language) {
|
|
606
|
-
str += '@' + expr.language;
|
|
607
|
-
} else if (!expr.datatype.equals(this.xsd.string)) {
|
|
608
|
-
str += '^^' + this.atomicTermToN3(expr.datatype, stats);
|
|
609
|
-
}
|
|
610
634
|
|
|
611
|
-
|
|
635
|
+
var str = this.stringToN3(expr.value);
|
|
612
636
|
|
|
613
|
-
|
|
614
|
-
|
|
637
|
+
if (expr.language) {
|
|
638
|
+
str += '@' + expr.language;
|
|
639
|
+
} else if (!expr.datatype.equals(this.xsd.string)) {
|
|
640
|
+
str += '^^' + this.atomicTermToN3(expr.datatype, stats);
|
|
641
|
+
}
|
|
615
642
|
|
|
616
|
-
|
|
617
|
-
throw new Error('Internal: atomicTermToN3 cannot handle ' + expr + ' of termType: ' + expr.termType);
|
|
618
|
-
}
|
|
619
|
-
}; // stringToN3: String escaping for N3
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
__Serializer.prototype.validPrefix = new RegExp(/^[a-zA-Z][a-zA-Z0-9]*$/);
|
|
623
|
-
__Serializer.prototype.forbidden1 = new RegExp(/[\\"\b\f\r\v\t\n\u0080-\uffff]/gm);
|
|
624
|
-
__Serializer.prototype.forbidden3 = new RegExp(/[\\"\b\f\r\v\u0080-\uffff]/gm);
|
|
625
|
-
|
|
626
|
-
__Serializer.prototype.stringToN3 = function stringToN3(str, flags) {
|
|
627
|
-
if (!flags) flags = 'e';
|
|
628
|
-
var res = '';
|
|
629
|
-
var i, j, k;
|
|
630
|
-
var delim;
|
|
631
|
-
var forbidden;
|
|
632
|
-
|
|
633
|
-
if (str.length > 20 && // Long enough to make sense
|
|
634
|
-
str.slice(-1) !== '"' && // corner case'
|
|
635
|
-
flags.indexOf('n') < 0 && ( // Force single line
|
|
636
|
-
str.indexOf('\n') > 0 || str.indexOf('"') > 0)) {
|
|
637
|
-
delim = '"""';
|
|
638
|
-
forbidden = __Serializer.prototype.forbidden3;
|
|
639
|
-
} else {
|
|
640
|
-
delim = '"';
|
|
641
|
-
forbidden = __Serializer.prototype.forbidden1;
|
|
642
|
-
}
|
|
643
|
+
return str;
|
|
643
644
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
var m = forbidden.exec(str.slice(i));
|
|
647
|
-
if (m == null) break;
|
|
648
|
-
j = i + forbidden.lastIndex - 1;
|
|
649
|
-
res += str.slice(i, j);
|
|
650
|
-
var ch = str[j];
|
|
645
|
+
case 'NamedNode':
|
|
646
|
+
return this.symbolToN3(expr);
|
|
651
647
|
|
|
652
|
-
|
|
653
|
-
|
|
648
|
+
default:
|
|
649
|
+
throw new Error('Internal: atomicTermToN3 cannot handle ' + expr + ' of termType: ' + expr.termType);
|
|
650
|
+
}
|
|
651
|
+
} // stringToN3: String escaping for N3
|
|
652
|
+
|
|
653
|
+
}, {
|
|
654
|
+
key: "stringToN3",
|
|
655
|
+
value: function stringToN3(str, flags) {
|
|
656
|
+
if (!flags) flags = 'e';
|
|
657
|
+
var res = '';
|
|
658
|
+
var i, j, k;
|
|
659
|
+
var delim;
|
|
660
|
+
var forbidden;
|
|
661
|
+
|
|
662
|
+
if (str.length > 20 && // Long enough to make sense
|
|
663
|
+
str.slice(-1) !== '"' && // corner case'
|
|
664
|
+
flags.indexOf('n') < 0 && ( // Force single line
|
|
665
|
+
str.indexOf('\n') > 0 || str.indexOf('"') > 0)) {
|
|
666
|
+
delim = '"""';
|
|
667
|
+
forbidden = this.forbidden3;
|
|
654
668
|
} else {
|
|
655
|
-
|
|
669
|
+
delim = '"';
|
|
670
|
+
forbidden = this.forbidden1;
|
|
671
|
+
}
|
|
656
672
|
|
|
657
|
-
|
|
658
|
-
|
|
673
|
+
for (i = 0; i < str.length;) {
|
|
674
|
+
forbidden.lastIndex = 0;
|
|
675
|
+
var m = forbidden.exec(str.slice(i));
|
|
676
|
+
if (m == null) break;
|
|
677
|
+
j = i + forbidden.lastIndex - 1;
|
|
678
|
+
res += str.slice(i, j);
|
|
679
|
+
var ch = str[j];
|
|
680
|
+
|
|
681
|
+
if (ch === '"' && delim === '"""' && str.slice(j, j + 3) !== '"""') {
|
|
682
|
+
res += ch;
|
|
659
683
|
} else {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
684
|
+
k = '\b\f\r\t\v\n\\"'.indexOf(ch); // No escaping of bell (7)?
|
|
685
|
+
|
|
686
|
+
if (k >= 0) {
|
|
687
|
+
res += '\\' + 'bfrtvn\\"'[k];
|
|
663
688
|
} else {
|
|
664
|
-
|
|
665
|
-
|
|
689
|
+
if (flags.indexOf('e') >= 0) {
|
|
690
|
+
// Unicode escaping in strings not unix style
|
|
691
|
+
res += "\\u" + ('000' + ch.charCodeAt(0).toString(16).toLowerCase()).slice(-4);
|
|
692
|
+
} else {
|
|
693
|
+
// no 'e' flag
|
|
694
|
+
res += ch;
|
|
695
|
+
}
|
|
666
696
|
}
|
|
667
697
|
}
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
i = j + 1;
|
|
671
|
-
}
|
|
672
698
|
|
|
673
|
-
|
|
674
|
-
|
|
699
|
+
i = j + 1;
|
|
700
|
+
}
|
|
675
701
|
|
|
702
|
+
return delim + res + str.slice(i) + delim;
|
|
703
|
+
} // A single symbol, either in <> or namespace notation
|
|
676
704
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
705
|
+
}, {
|
|
706
|
+
key: "symbolToN3",
|
|
707
|
+
value: function symbolToN3(x) {
|
|
708
|
+
// c.f. symbolString() in notation3.py
|
|
709
|
+
var uri = x.uri;
|
|
710
|
+
var j = uri.indexOf('#');
|
|
681
711
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
712
|
+
if (j < 0 && this.flags.indexOf('/') < 0) {
|
|
713
|
+
j = uri.lastIndexOf('/');
|
|
714
|
+
}
|
|
685
715
|
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
716
|
+
if (j >= 0 && this.flags.indexOf('p') < 0 && ( // Can split at namespace but only if http[s]: URI or file: or ws[s] (why not others?)
|
|
717
|
+
uri.indexOf('http') === 0 || uri.indexOf('ws') === 0 || uri.indexOf('file') === 0)) {
|
|
718
|
+
var canSplit = true;
|
|
689
719
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
720
|
+
for (var k = j + 1; k < uri.length; k++) {
|
|
721
|
+
if (this._notNameChars.indexOf(uri[k]) >= 0) {
|
|
722
|
+
canSplit = false;
|
|
723
|
+
break;
|
|
724
|
+
}
|
|
694
725
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
726
|
+
/*
|
|
727
|
+
if (uri.slice(0, j + 1) === this.base + '#') { // base-relative
|
|
728
|
+
if (canSplit) {
|
|
729
|
+
return ':' + uri.slice(j + 1) // assume deafult ns is local
|
|
730
|
+
} else {
|
|
731
|
+
return '<#' + uri.slice(j + 1) + '>'
|
|
732
|
+
}
|
|
702
733
|
}
|
|
703
|
-
|
|
704
|
-
*/
|
|
734
|
+
*/
|
|
705
735
|
|
|
706
736
|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
737
|
+
if (canSplit) {
|
|
738
|
+
var localid = uri.slice(j + 1);
|
|
739
|
+
var namesp = uri.slice(0, j + 1);
|
|
710
740
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
741
|
+
if (this.defaultNamespace && this.defaultNamespace === namesp && this.flags.indexOf('d') < 0) {
|
|
742
|
+
// d -> suppress default
|
|
743
|
+
if (this.flags.indexOf('k') >= 0 && this.keyords.indexOf(localid) < 0) {
|
|
744
|
+
return localid;
|
|
745
|
+
}
|
|
716
746
|
|
|
717
|
-
|
|
718
|
-
|
|
747
|
+
return ':' + localid;
|
|
748
|
+
} // this.checkIntegrity() // @@@ Remove when not testing
|
|
719
749
|
|
|
720
750
|
|
|
721
|
-
|
|
722
|
-
|
|
751
|
+
var prefix = this.prefixes[namesp];
|
|
752
|
+
if (!prefix) prefix = this.makeUpPrefix(namesp);
|
|
723
753
|
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
754
|
+
if (prefix) {
|
|
755
|
+
this.namespacesUsed[namesp] = true;
|
|
756
|
+
return prefix + ':' + localid;
|
|
757
|
+
} // Fall though if can't do qname
|
|
728
758
|
|
|
759
|
+
}
|
|
729
760
|
}
|
|
730
|
-
}
|
|
731
761
|
|
|
732
|
-
|
|
733
|
-
|
|
762
|
+
return this.explicitURI(uri);
|
|
763
|
+
} // /////////////////////////// Quad store serialization
|
|
764
|
+
// @para. write - a function taking a single string to be output
|
|
765
|
+
//
|
|
766
|
+
|
|
767
|
+
}, {
|
|
768
|
+
key: "writeStore",
|
|
769
|
+
value: function writeStore(write) {
|
|
770
|
+
var kb = this.store;
|
|
771
|
+
var fetcher = kb.fetcher;
|
|
772
|
+
var session = fetcher && fetcher.appNode; // The core data
|
|
773
|
+
|
|
774
|
+
var sources = this.store.index[3];
|
|
775
|
+
|
|
776
|
+
for (var s in sources) {
|
|
777
|
+
// -> assume we can use -> as short for log:semantics
|
|
778
|
+
var source = kb.fromNT(s);
|
|
779
|
+
if (session && source.equals(session)) continue;
|
|
780
|
+
write('\n' + this.atomicTermToN3(source) + ' ' + this.atomicTermToN3(kb.sym('http://www.w3.org/2000/10/swap/log#semantics')) + ' { ' + this.statementsToN3(kb.statementsMatching(undefined, undefined, undefined, source)) + ' }.\n');
|
|
781
|
+
} // The metadata from HTTP interactions:
|
|
782
|
+
|
|
783
|
+
|
|
784
|
+
kb.statementsMatching(undefined, kb.sym('http://www.w3.org/2007/ont/link#requestedURI')).map(function (st) {
|
|
785
|
+
write('\n<' + st.object.value + '> log:metadata {\n');
|
|
786
|
+
var sts = kb.statementsMatching(undefined, undefined, undefined, st.subject);
|
|
787
|
+
write(this.statementsToN3(this.statementsToN3(sts)));
|
|
788
|
+
write('}.\n');
|
|
789
|
+
}); // Inferences we have made ourselves not attributable to anyone else
|
|
790
|
+
|
|
791
|
+
var metaSources = [];
|
|
792
|
+
if (session) metaSources.push(session);
|
|
793
|
+
var metadata = [];
|
|
794
|
+
metaSources.map(function (source) {
|
|
795
|
+
metadata = metadata.concat(kb.statementsMatching(undefined, undefined, undefined, source));
|
|
796
|
+
});
|
|
797
|
+
write(this.statementsToN3(metadata));
|
|
798
|
+
} // ////////////////////////////////////////////// XML serialization
|
|
734
799
|
|
|
800
|
+
}, {
|
|
801
|
+
key: "statementsToXML",
|
|
802
|
+
value: function statementsToXML(sts) {
|
|
803
|
+
var indent = 4;
|
|
804
|
+
var width = 80;
|
|
805
|
+
var namespaceCounts = []; // which have been used
|
|
735
806
|
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
}
|
|
807
|
+
namespaceCounts['http://www.w3.org/1999/02/22-rdf-syntax-ns#'] = true;
|
|
808
|
+
var liPrefix = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#_'; // prefix for ordered list items
|
|
809
|
+
// //////////////////////// Arrange the bits of XML text
|
|
740
810
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
var k;
|
|
811
|
+
var spaces = function spaces(n) {
|
|
812
|
+
var s = '';
|
|
744
813
|
|
|
745
|
-
|
|
746
|
-
|
|
814
|
+
for (var i = 0; i < n; i++) {
|
|
815
|
+
s += ' ';
|
|
816
|
+
}
|
|
747
817
|
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
} else if (k > 126) {
|
|
751
|
-
res += "\\u" + ('0000' + k.toString(16)).slice(-4);
|
|
752
|
-
} else {
|
|
753
|
-
res += str[i];
|
|
754
|
-
}
|
|
755
|
-
}
|
|
818
|
+
return s;
|
|
819
|
+
};
|
|
756
820
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
// @para. write - a function taking a single string to be output
|
|
760
|
-
//
|
|
821
|
+
var XMLtreeToLine = function XMLtreeToLine(tree) {
|
|
822
|
+
var str = '';
|
|
761
823
|
|
|
824
|
+
for (var i = 0; i < tree.length; i++) {
|
|
825
|
+
var branch = tree[i];
|
|
826
|
+
var s2 = typeof branch === 'string' ? branch : XMLtreeToLine(branch);
|
|
827
|
+
str += s2;
|
|
828
|
+
}
|
|
762
829
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
var fetcher = kb.fetcher;
|
|
766
|
-
var session = fetcher && fetcher.appNode; // The core data
|
|
830
|
+
return str;
|
|
831
|
+
}; // Convert a nested tree of lists and strings to a string
|
|
767
832
|
|
|
768
|
-
var sources = this.store.index[3];
|
|
769
833
|
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
} // The metadata from HTTP interactions:
|
|
834
|
+
var XMLtreeToString = function XMLtreeToString(tree, level) {
|
|
835
|
+
var str = '';
|
|
836
|
+
var line;
|
|
837
|
+
var lastLength = 100000;
|
|
838
|
+
if (!level) level = 0;
|
|
776
839
|
|
|
840
|
+
for (var i = 0; i < tree.length; i++) {
|
|
841
|
+
var branch = tree[i];
|
|
777
842
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
var sts = kb.statementsMatching(undefined, undefined, undefined, st.subject);
|
|
781
|
-
write(this.statementsToN3(this.statementsToN3(sts)));
|
|
782
|
-
write('}.\n');
|
|
783
|
-
}); // Inferences we have made ourselves not attributable to anyone else
|
|
843
|
+
if (typeof branch !== 'string') {
|
|
844
|
+
var substr = XMLtreeToString(branch, level + 1);
|
|
784
845
|
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
metaSources.map(function (source) {
|
|
789
|
-
metadata = metadata.concat(kb.statementsMatching(undefined, undefined, undefined, source));
|
|
790
|
-
});
|
|
791
|
-
write(this.statementsToN3(metadata));
|
|
792
|
-
}; // ////////////////////////////////////////////// XML serialization
|
|
846
|
+
if (substr.length < 10 * (width - indent * level) && substr.indexOf('"""') < 0) {
|
|
847
|
+
// Don't mess up multiline strings
|
|
848
|
+
line = XMLtreeToLine(branch);
|
|
793
849
|
|
|
850
|
+
if (line.length < width - indent * level) {
|
|
851
|
+
branch = ' ' + line; // @@ Hack: treat as string below
|
|
794
852
|
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
var namespaceCounts = []; // which have been used
|
|
853
|
+
substr = '';
|
|
854
|
+
}
|
|
855
|
+
}
|
|
799
856
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
857
|
+
if (substr) lastLength = 10000;
|
|
858
|
+
str += substr;
|
|
859
|
+
}
|
|
803
860
|
|
|
804
|
-
|
|
805
|
-
|
|
861
|
+
if (typeof branch === 'string') {
|
|
862
|
+
if (lastLength < indent * level + 4) {
|
|
863
|
+
// continue
|
|
864
|
+
str = str.slice(0, -1) + ' ' + branch + '\n';
|
|
865
|
+
lastLength += branch.length + 1;
|
|
866
|
+
} else {
|
|
867
|
+
line = spaces(indent * level) + branch;
|
|
868
|
+
str += line + '\n';
|
|
869
|
+
lastLength = line.length;
|
|
870
|
+
}
|
|
871
|
+
} else {// not string
|
|
872
|
+
}
|
|
873
|
+
}
|
|
806
874
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
}
|
|
875
|
+
return str;
|
|
876
|
+
};
|
|
810
877
|
|
|
811
|
-
|
|
812
|
-
|
|
878
|
+
function statementListToXMLTreeMethod(statements) {
|
|
879
|
+
this.suggestPrefix('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
|
|
880
|
+
var stats = this.rootSubjects(statements);
|
|
881
|
+
var roots = stats.roots;
|
|
882
|
+
var results = [];
|
|
813
883
|
|
|
814
|
-
|
|
815
|
-
|
|
884
|
+
for (var i = 0; i < roots.length; i++) {
|
|
885
|
+
var root = roots[i];
|
|
886
|
+
results.push(subjectXMLTree(root, stats));
|
|
887
|
+
}
|
|
816
888
|
|
|
817
|
-
|
|
818
|
-
var branch = tree[i];
|
|
819
|
-
var s2 = typeof branch === 'string' ? branch : XMLtreeToLine(branch);
|
|
820
|
-
str += s2;
|
|
889
|
+
return results;
|
|
821
890
|
}
|
|
822
891
|
|
|
823
|
-
|
|
824
|
-
}; // Convert a nested tree of lists and strings to a string
|
|
825
|
-
|
|
892
|
+
var statementListToXMLTree = statementListToXMLTreeMethod.bind(this);
|
|
826
893
|
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
for (var i = 0; i < tree.length; i++) {
|
|
834
|
-
var branch = tree[i];
|
|
835
|
-
|
|
836
|
-
if (typeof branch !== 'string') {
|
|
837
|
-
var substr = XMLtreeToString(branch, level + 1);
|
|
894
|
+
function escapeForXML(str) {
|
|
895
|
+
if (typeof str === 'undefined') return '@@@undefined@@@@';
|
|
896
|
+
return str.replace(/[&<"]/g, function (m) {
|
|
897
|
+
switch (m[0]) {
|
|
898
|
+
case '&':
|
|
899
|
+
return '&';
|
|
838
900
|
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
line = XMLtreeToLine(branch);
|
|
901
|
+
case '<':
|
|
902
|
+
return '<';
|
|
842
903
|
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
substr = '';
|
|
847
|
-
}
|
|
904
|
+
case '"':
|
|
905
|
+
return '"';
|
|
906
|
+
// '
|
|
848
907
|
}
|
|
908
|
+
});
|
|
909
|
+
}
|
|
849
910
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
if (typeof branch === 'string') {
|
|
855
|
-
if (lastLength < indent * level + 4) {
|
|
856
|
-
// continue
|
|
857
|
-
str = str.slice(0, -1) + ' ' + branch + '\n';
|
|
858
|
-
lastLength += branch.length + 1;
|
|
859
|
-
} else {
|
|
860
|
-
line = spaces(indent * level) + branch;
|
|
861
|
-
str += line + '\n';
|
|
862
|
-
lastLength = line.length;
|
|
863
|
-
}
|
|
864
|
-
} else {// not string
|
|
865
|
-
}
|
|
911
|
+
function relURIMethod(term) {
|
|
912
|
+
return escapeForXML(this.base ? Util.uri.refTo(this.base, term.uri) : term.uri);
|
|
866
913
|
}
|
|
867
914
|
|
|
868
|
-
|
|
869
|
-
};
|
|
915
|
+
var relURI = relURIMethod.bind(this); // The tree for a subject
|
|
870
916
|
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
var results = [];
|
|
917
|
+
function subjectXMLTreeMethod(subject, stats) {
|
|
918
|
+
var results = [];
|
|
919
|
+
var type, t, st, pred;
|
|
920
|
+
var sts = stats.subjects[this.toStr(subject)]; // relevant statements
|
|
876
921
|
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
922
|
+
if (typeof sts === 'undefined') {
|
|
923
|
+
// empty bnode
|
|
924
|
+
return propertyXMLTree(subject, stats);
|
|
925
|
+
} // Sort only on the predicate, leave the order at object
|
|
926
|
+
// level undisturbed. This leaves multilingual content in
|
|
927
|
+
// the order of entry (for partner literals), which helps
|
|
928
|
+
// readability.
|
|
929
|
+
//
|
|
930
|
+
// For the predicate sort, we attempt to split the uri
|
|
931
|
+
// as a hint to the sequence
|
|
881
932
|
|
|
882
|
-
return results;
|
|
883
|
-
}
|
|
884
933
|
|
|
885
|
-
|
|
934
|
+
sts.sort(function (a, b) {
|
|
935
|
+
var ap = a.predicate.uri;
|
|
936
|
+
var bp = b.predicate.uri;
|
|
886
937
|
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
case '&':
|
|
892
|
-
return '&';
|
|
938
|
+
if (ap.substring(0, liPrefix.length) === liPrefix || bp.substring(0, liPrefix.length) === liPrefix) {
|
|
939
|
+
// we're only interested in sorting list items
|
|
940
|
+
return ap.localeCompare(bp);
|
|
941
|
+
}
|
|
893
942
|
|
|
894
|
-
|
|
895
|
-
|
|
943
|
+
var as = ap.substring(liPrefix.length);
|
|
944
|
+
var bs = bp.substring(liPrefix.length);
|
|
945
|
+
var an = parseInt(as, 10);
|
|
946
|
+
var bn = parseInt(bs, 10);
|
|
896
947
|
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
});
|
|
902
|
-
}
|
|
948
|
+
if (isNaN(an) || isNaN(bn) || an !== as || bn !== bs) {
|
|
949
|
+
// we only care about integers
|
|
950
|
+
return ap.localeCompare(bp);
|
|
951
|
+
}
|
|
903
952
|
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
}
|
|
953
|
+
return an - bn;
|
|
954
|
+
});
|
|
907
955
|
|
|
908
|
-
|
|
956
|
+
for (var i = 0; i < sts.length; i++) {
|
|
957
|
+
st = sts[i]; // look for a type
|
|
909
958
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
959
|
+
if (st.predicate.uri === 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' && !type && st.object.termType === 'NamedNode') {
|
|
960
|
+
type = st.object;
|
|
961
|
+
continue; // don't include it as a child element
|
|
962
|
+
} // see whether predicate can be replaced with "li"
|
|
914
963
|
|
|
915
|
-
if (typeof sts === 'undefined') {
|
|
916
|
-
// empty bnode
|
|
917
|
-
return propertyXMLTree(subject, stats);
|
|
918
|
-
} // Sort only on the predicate, leave the order at object
|
|
919
|
-
// level undisturbed. This leaves multilingual content in
|
|
920
|
-
// the order of entry (for partner literals), which helps
|
|
921
|
-
// readability.
|
|
922
|
-
//
|
|
923
|
-
// For the predicate sort, we attempt to split the uri
|
|
924
|
-
// as a hint to the sequence
|
|
925
964
|
|
|
965
|
+
pred = st.predicate;
|
|
926
966
|
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
var bp = b.predicate.uri;
|
|
967
|
+
if (pred.uri.substr(0, liPrefix.length) === liPrefix) {
|
|
968
|
+
var number = pred.uri.substr(liPrefix.length); // make sure these are actually numeric list items
|
|
930
969
|
|
|
931
|
-
|
|
932
|
-
// we're only interested in sorting list items
|
|
933
|
-
return ap.localeCompare(bp);
|
|
934
|
-
}
|
|
970
|
+
var intNumber = parseInt(number, 10);
|
|
935
971
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
972
|
+
if (number === intNumber.toString()) {
|
|
973
|
+
// was numeric; don't need to worry about ordering since we've already
|
|
974
|
+
// sorted the statements
|
|
975
|
+
pred = this.rdfFactory.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#li');
|
|
976
|
+
}
|
|
977
|
+
}
|
|
940
978
|
|
|
941
|
-
|
|
942
|
-
// we only care about integers
|
|
943
|
-
return ap.localeCompare(bp);
|
|
944
|
-
}
|
|
979
|
+
t = qname(pred);
|
|
945
980
|
|
|
946
|
-
|
|
947
|
-
|
|
981
|
+
switch (st.object.termType) {
|
|
982
|
+
case 'BlankNode':
|
|
983
|
+
if (stats.incoming[st.object].length === 1) {
|
|
984
|
+
// there should always be something in the incoming array for a bnode
|
|
985
|
+
results = results.concat(['<' + t + ' rdf:parseType="Resource">', subjectXMLTree(st.object, stats), '</' + t + '>']);
|
|
986
|
+
} else {
|
|
987
|
+
results = results.concat(['<' + t + ' rdf:nodeID="' + st.object.toNT().slice(2) + '"/>']);
|
|
988
|
+
}
|
|
948
989
|
|
|
949
|
-
|
|
950
|
-
st = sts[i]; // look for a type
|
|
990
|
+
break;
|
|
951
991
|
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
} // see whether predicate can be replaced with "li"
|
|
992
|
+
case 'NamedNode':
|
|
993
|
+
results = results.concat(['<' + t + ' rdf:resource="' + relURI(st.object) + '"/>']);
|
|
994
|
+
break;
|
|
956
995
|
|
|
996
|
+
case 'Literal':
|
|
997
|
+
results = results.concat(['<' + t + (st.object.datatype.equals(this.xsd.string) ? '' : ' rdf:datatype="' + escapeForXML(st.object.datatype.uri) + '"') + (st.object.language ? ' xml:lang="' + st.object.language + '"' : '') + '>' + escapeForXML(st.object.value) + '</' + t + '>']);
|
|
998
|
+
break;
|
|
957
999
|
|
|
958
|
-
|
|
1000
|
+
case 'Collection':
|
|
1001
|
+
results = results.concat(['<' + t + ' rdf:parseType="Collection">', collectionXMLTree(st.object, stats), '</' + t + '>']);
|
|
1002
|
+
break;
|
|
959
1003
|
|
|
960
|
-
|
|
961
|
-
|
|
1004
|
+
default:
|
|
1005
|
+
throw new Error("Can't serialize object of type " + st.object.termType + ' into XML');
|
|
1006
|
+
} // switch
|
|
962
1007
|
|
|
963
|
-
|
|
1008
|
+
}
|
|
964
1009
|
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
1010
|
+
var tag = type ? qname(type) : 'rdf:Description';
|
|
1011
|
+
var attrs = '';
|
|
1012
|
+
|
|
1013
|
+
if (subject.termType === 'BlankNode') {
|
|
1014
|
+
if (!stats.incoming[subject] || stats.incoming[subject].length !== 1) {
|
|
1015
|
+
// not an anonymous bnode
|
|
1016
|
+
attrs = ' rdf:nodeID="' + subject.toNT().slice(2) + '"';
|
|
969
1017
|
}
|
|
1018
|
+
} else {
|
|
1019
|
+
attrs = ' rdf:about="' + relURI(subject) + '"';
|
|
970
1020
|
}
|
|
971
1021
|
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
switch (st.object.termType) {
|
|
975
|
-
case 'BlankNode':
|
|
976
|
-
if (stats.incoming[st.object].length === 1) {
|
|
977
|
-
// there should always be something in the incoming array for a bnode
|
|
978
|
-
results = results.concat(['<' + t + ' rdf:parseType="Resource">', subjectXMLTree(st.object, stats), '</' + t + '>']);
|
|
979
|
-
} else {
|
|
980
|
-
results = results.concat(['<' + t + ' rdf:nodeID="' + st.object.toNT().slice(2) + '"/>']);
|
|
981
|
-
}
|
|
1022
|
+
return ['<' + tag + attrs + '>'].concat([results]).concat(['</' + tag + '>']);
|
|
1023
|
+
}
|
|
982
1024
|
|
|
983
|
-
|
|
1025
|
+
var subjectXMLTree = subjectXMLTreeMethod.bind(this);
|
|
984
1026
|
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
break;
|
|
1027
|
+
function collectionXMLTree(subject, stats) {
|
|
1028
|
+
var res = [];
|
|
988
1029
|
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1030
|
+
for (var i = 0; i < subject.elements.length; i++) {
|
|
1031
|
+
res.push(subjectXMLTree(subject.elements[i], stats));
|
|
1032
|
+
}
|
|
992
1033
|
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
break;
|
|
1034
|
+
return res;
|
|
1035
|
+
} // The property tree for a single subject or anonymos node
|
|
996
1036
|
|
|
997
|
-
default:
|
|
998
|
-
throw new Error("Can't serialize object of type " + st.object.termType + ' into XML');
|
|
999
|
-
} // switch
|
|
1000
1037
|
|
|
1001
|
-
|
|
1038
|
+
function propertyXMLTreeMethod(subject, stats) {
|
|
1039
|
+
var results = [];
|
|
1040
|
+
var sts = stats.subjects[this.toStr(subject)]; // relevant statements
|
|
1002
1041
|
|
|
1003
|
-
|
|
1004
|
-
var attrs = '';
|
|
1042
|
+
if (!sts) return results; // No relevant statements
|
|
1005
1043
|
|
|
1006
|
-
|
|
1007
|
-
if (!stats.incoming[subject] || stats.incoming[subject].length !== 1) {
|
|
1008
|
-
// not an anonymous bnode
|
|
1009
|
-
attrs = ' rdf:nodeID="' + subject.toNT().slice(2) + '"';
|
|
1010
|
-
}
|
|
1011
|
-
} else {
|
|
1012
|
-
attrs = ' rdf:about="' + relURI(subject) + '"';
|
|
1013
|
-
}
|
|
1044
|
+
sts.sort();
|
|
1014
1045
|
|
|
1015
|
-
|
|
1016
|
-
|
|
1046
|
+
for (var i = 0; i < sts.length; i++) {
|
|
1047
|
+
var st = sts[i];
|
|
1017
1048
|
|
|
1018
|
-
|
|
1049
|
+
switch (st.object.termType) {
|
|
1050
|
+
case 'BlankNode':
|
|
1051
|
+
if (stats.rootsHash[st.object.toNT()]) {
|
|
1052
|
+
// This bnode has been done as a root -- no content here @@ what bout first time
|
|
1053
|
+
results = results.concat(['<' + qname(st.predicate) + ' rdf:nodeID="' + st.object.toNT().slice(2) + '">', '</' + qname(st.predicate) + '>']);
|
|
1054
|
+
} else {
|
|
1055
|
+
results = results.concat(['<' + qname(st.predicate) + ' rdf:parseType="Resource">', propertyXMLTree(st.object, stats), '</' + qname(st.predicate) + '>']);
|
|
1056
|
+
}
|
|
1019
1057
|
|
|
1020
|
-
|
|
1021
|
-
var res = [];
|
|
1058
|
+
break;
|
|
1022
1059
|
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1060
|
+
case 'NamedNode':
|
|
1061
|
+
results = results.concat(['<' + qname(st.predicate) + ' rdf:resource="' + relURI(st.object) + '"/>']);
|
|
1062
|
+
break;
|
|
1026
1063
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1064
|
+
case 'Literal':
|
|
1065
|
+
results = results.concat(['<' + qname(st.predicate) + (st.object.datatype.equals(this.xsd.string) ? '' : ' rdf:datatype="' + escapeForXML(st.object.datatype.value) + '"') + (st.object.language ? ' xml:lang="' + st.object.language + '"' : '') + '>' + escapeForXML(st.object.value) + '</' + qname(st.predicate) + '>']);
|
|
1066
|
+
break;
|
|
1029
1067
|
|
|
1068
|
+
case 'Collection':
|
|
1069
|
+
results = results.concat(['<' + qname(st.predicate) + ' rdf:parseType="Collection">', collectionXMLTree(st.object, stats), '</' + qname(st.predicate) + '>']);
|
|
1070
|
+
break;
|
|
1030
1071
|
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1072
|
+
default:
|
|
1073
|
+
throw new Error("Can't serialize object of type " + st.object.termType + ' into XML');
|
|
1074
|
+
} // switch
|
|
1034
1075
|
|
|
1035
|
-
|
|
1076
|
+
}
|
|
1036
1077
|
|
|
1037
|
-
|
|
1078
|
+
return results;
|
|
1079
|
+
}
|
|
1038
1080
|
|
|
1039
|
-
|
|
1040
|
-
var st = sts[i];
|
|
1081
|
+
var propertyXMLTree = propertyXMLTreeMethod.bind(this);
|
|
1041
1082
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
// This bnode has been done as a root -- no content here @@ what bout first time
|
|
1046
|
-
results = results.concat(['<' + qname(st.predicate) + ' rdf:nodeID="' + st.object.toNT().slice(2) + '">', '</' + qname(st.predicate) + '>']);
|
|
1047
|
-
} else {
|
|
1048
|
-
results = results.concat(['<' + qname(st.predicate) + ' rdf:parseType="Resource">', propertyXMLTree(st.object, stats), '</' + qname(st.predicate) + '>']);
|
|
1049
|
-
}
|
|
1083
|
+
function qnameMethod(term) {
|
|
1084
|
+
var uri = term.uri;
|
|
1085
|
+
var j = uri.indexOf('#');
|
|
1050
1086
|
|
|
1051
|
-
|
|
1087
|
+
if (j < 0 && this.flags.indexOf('/') < 0) {
|
|
1088
|
+
j = uri.lastIndexOf('/');
|
|
1089
|
+
}
|
|
1052
1090
|
|
|
1053
|
-
|
|
1054
|
-
results = results.concat(['<' + qname(st.predicate) + ' rdf:resource="' + relURI(st.object) + '"/>']);
|
|
1055
|
-
break;
|
|
1091
|
+
if (j < 0) throw new Error('Cannot make qname out of <' + uri + '>');
|
|
1056
1092
|
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1093
|
+
for (var k = j + 1; k < uri.length; k++) {
|
|
1094
|
+
if (this._notNameChars.indexOf(uri[k]) >= 0) {
|
|
1095
|
+
throw new Error('Invalid character "' + uri[k] + '" cannot be in XML qname for URI: ' + uri);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1060
1098
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
break;
|
|
1099
|
+
var localid = uri.slice(j + 1);
|
|
1100
|
+
var namesp = uri.slice(0, j + 1);
|
|
1064
1101
|
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1102
|
+
if (this.defaultNamespace && this.defaultNamespace === namesp && this.flags.indexOf('d') < 0) {
|
|
1103
|
+
// d -> suppress default
|
|
1104
|
+
return localid;
|
|
1105
|
+
}
|
|
1068
1106
|
|
|
1107
|
+
var prefix = this.prefixes[namesp];
|
|
1108
|
+
if (!prefix) prefix = this.makeUpPrefix(namesp);
|
|
1109
|
+
namespaceCounts[namesp] = true;
|
|
1110
|
+
return prefix + ':' + localid;
|
|
1069
1111
|
}
|
|
1070
1112
|
|
|
1071
|
-
|
|
1072
|
-
}
|
|
1113
|
+
var qname = qnameMethod.bind(this); // Body of toXML:
|
|
1073
1114
|
|
|
1074
|
-
|
|
1115
|
+
var tree = statementListToXMLTree(sts);
|
|
1116
|
+
var str = '<rdf:RDF';
|
|
1075
1117
|
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
var j = uri.indexOf('#');
|
|
1079
|
-
|
|
1080
|
-
if (j < 0 && this.flags.indexOf('/') < 0) {
|
|
1081
|
-
j = uri.lastIndexOf('/');
|
|
1118
|
+
if (this.defaultNamespace) {
|
|
1119
|
+
str += ' xmlns="' + escapeForXML(this.defaultNamespace) + '"';
|
|
1082
1120
|
}
|
|
1083
1121
|
|
|
1084
|
-
|
|
1122
|
+
for (var ns in namespaceCounts) {
|
|
1123
|
+
if (!namespaceCounts.hasOwnProperty(ns)) continue; // Rel uris in xml ns is not strictly allowed in the XMLNS spec but needed in practice often
|
|
1085
1124
|
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
throw new Error('Invalid character "' + uri[k] + '" cannot be in XML qname for URI: ' + uri);
|
|
1089
|
-
}
|
|
1125
|
+
var ns2 = this.base && this.flags.includes('z') ? Util.uri.refTo(this.base, ns) : ns;
|
|
1126
|
+
str += '\n xmlns:' + this.prefixes[ns] + '="' + escapeForXML(ns2) + '"';
|
|
1090
1127
|
}
|
|
1091
1128
|
|
|
1092
|
-
|
|
1093
|
-
var
|
|
1129
|
+
str += '>';
|
|
1130
|
+
var tree2 = [str, tree, '</rdf:RDF>']; // @@ namespace declrations
|
|
1094
1131
|
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
return localid;
|
|
1098
|
-
}
|
|
1132
|
+
return XMLtreeToString(tree2, -1);
|
|
1133
|
+
} // End @@ body
|
|
1099
1134
|
|
|
1100
|
-
|
|
1101
|
-
if (!prefix) prefix = this.makeUpPrefix(namesp);
|
|
1102
|
-
namespaceCounts[namesp] = true;
|
|
1103
|
-
return prefix + ':' + localid;
|
|
1104
|
-
}
|
|
1135
|
+
}]);
|
|
1105
1136
|
|
|
1106
|
-
|
|
1137
|
+
return Serializer;
|
|
1138
|
+
}(); // String escaping utilities
|
|
1107
1139
|
|
|
1108
|
-
|
|
1109
|
-
|
|
1140
|
+
function hexify(str) {
|
|
1141
|
+
// also used in parser
|
|
1142
|
+
return encodeURI(str);
|
|
1143
|
+
}
|
|
1110
1144
|
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1145
|
+
function backslashUify(str) {
|
|
1146
|
+
var res = '';
|
|
1147
|
+
var k;
|
|
1114
1148
|
|
|
1115
|
-
|
|
1116
|
-
|
|
1149
|
+
for (var i = 0; i < str.length; i++) {
|
|
1150
|
+
k = str.charCodeAt(i);
|
|
1117
1151
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1152
|
+
if (k > 65535) {
|
|
1153
|
+
res += "\\U" + ('00000000' + k.toString(16)).slice(-8); // convert to upper?
|
|
1154
|
+
} else if (k > 126) {
|
|
1155
|
+
res += "\\u" + ('0000' + k.toString(16)).slice(-4);
|
|
1156
|
+
} else {
|
|
1157
|
+
res += str[i];
|
|
1120
1158
|
}
|
|
1159
|
+
}
|
|
1121
1160
|
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
return XMLtreeToString(tree2, -1);
|
|
1126
|
-
}; // End @@ body
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
var Serializer = function Serializer(store) {
|
|
1130
|
-
return new __Serializer(store);
|
|
1131
|
-
};
|
|
1132
|
-
|
|
1133
|
-
return Serializer;
|
|
1134
|
-
})();
|
|
1161
|
+
return res;
|
|
1162
|
+
}
|