n3 2.2.11 → 2.2.13
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/README.md +65 -0
- package/browser/n3.esm.min.js +5 -5
- package/browser/n3.min.js +1 -1
- package/lib/N3Lexer.js +15 -9
- package/lib/N3Parser.js +44 -3
- package/package.json +1 -1
- package/src/N3Lexer.js +16 -11
- package/src/N3Parser.js +51 -2
package/README.md
CHANGED
|
@@ -180,6 +180,15 @@ The parser can output a backwards chaining rule such as `_:q <= _:p.` in two way
|
|
|
180
180
|
const parser = new N3.Parser({ isImpliedBy: true });
|
|
181
181
|
```
|
|
182
182
|
|
|
183
|
+
By default, an empty formula `{}` is kept as a blank node graph term.
|
|
184
|
+
The [N3 spec tests](https://w3c-cg.github.io/N3/tests/)
|
|
185
|
+
(and the direction discussed in [w3c-cg/N3#185](https://github.com/w3c-cg/N3/issues/185))
|
|
186
|
+
read it as the boolean literal `"true"^^xsd:boolean` instead;
|
|
187
|
+
the `emptyFormulaAsTrue` flag enables that behavior:
|
|
188
|
+
```JavaScript
|
|
189
|
+
const parser = new N3.Parser({ format: 'text/n3', emptyFormulaAsTrue: true });
|
|
190
|
+
```
|
|
191
|
+
|
|
183
192
|
### From an RDF stream to quads
|
|
184
193
|
|
|
185
194
|
`N3.Parser` can parse [Node.js streams](http://nodejs.org/api/stream.html) as they grow,
|
|
@@ -496,6 +505,62 @@ and allows a mixture of different syntaxes.
|
|
|
496
505
|
Pass a `format` option to the constructor with the name or MIME type of a format
|
|
497
506
|
for strict, fault-intolerant behavior.
|
|
498
507
|
|
|
508
|
+
### Validation
|
|
509
|
+
The **parser** validates the _syntax_ of the selected format's grammar, with the following exceptions:
|
|
510
|
+
- IRIs are not checked for full [RFC 3987](https://www.rfc-editor.org/rfc/rfc3987) well-formedness
|
|
511
|
+
(`<http://example.org/%ZZ>` parses),
|
|
512
|
+
and relative IRIs remain relative when no `baseIRI` option is given;
|
|
513
|
+
- literal values are not checked against their datatype (`"abc"^^xsd:integer` parses);
|
|
514
|
+
- language tags are checked against the grammar, not against [BCP 47](https://www.rfc-editor.org/rfc/rfc5646);
|
|
515
|
+
|
|
516
|
+
The **writer** trusts the terms it is given. Quads constructed with invalid term values are serialized as-is and can yield invalid documents.
|
|
517
|
+
|
|
518
|
+
Therefore, term validation should be done post-parsing to ensure that valid RDF terms should be produced.
|
|
519
|
+
|
|
520
|
+
One should also ensure that terms are valid prior to being passed into the writer; either by validation, or ensuring that valid RDF will always be produced by the application logic producing the terms.
|
|
521
|
+
|
|
522
|
+
The following code snipped shows how to validate that NamedNodes and Literals are validly formed. Depending on your application you may wish to apply further validation: such as ensuring that nested Quad terms are valid in RDF 1.2, and ensuring that `termTypes` are only occuring in the positions that is valid for RDF 1.1 and RDF 1.2.
|
|
523
|
+
```JavaScript
|
|
524
|
+
const { Transform } = require('stream');
|
|
525
|
+
const { validateIri, IriValidationStrategy } = require('validate-iri');
|
|
526
|
+
const { validators } = require('rdf-validate-datatype');
|
|
527
|
+
const { parse: parseLanguageTag } = require('bcp-47');
|
|
528
|
+
|
|
529
|
+
function validateTerm(term) {
|
|
530
|
+
switch (term.termType) {
|
|
531
|
+
case 'NamedNode': // RDF requires absolute IRIs
|
|
532
|
+
return validateIri(term.value, IriValidationStrategy.Strict) || null;
|
|
533
|
+
case 'Literal':
|
|
534
|
+
if (term.language) {
|
|
535
|
+
let invalid = false;
|
|
536
|
+
parseLanguageTag(term.language, { warning: () => { invalid = true; } });
|
|
537
|
+
return invalid ? new Error(`Invalid language tag "${term.language}"`) : null;
|
|
538
|
+
}
|
|
539
|
+
const validate = validators.find(term.datatype);
|
|
540
|
+
return validate && !validate(term.value)
|
|
541
|
+
? new Error(`Invalid value "${term.value}" for datatype ${term.datatype.value}`)
|
|
542
|
+
: null; // unknown datatypes cannot be judged
|
|
543
|
+
default:
|
|
544
|
+
return null;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
const quadStream = fs.createReadStream('data.ttl')
|
|
549
|
+
.pipe(new N3.StreamParser())
|
|
550
|
+
.pipe(new Transform({
|
|
551
|
+
objectMode: true,
|
|
552
|
+
transform(quad, encoding, done) {
|
|
553
|
+
const error = validateTerm(quad.subject) || validateTerm(quad.predicate) ||
|
|
554
|
+
validateTerm(quad.object) || validateTerm(quad.graph);
|
|
555
|
+
done(error, error ? undefined : quad); // or: skip/collect instead of failing
|
|
556
|
+
},
|
|
557
|
+
}));
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
Parser-level opt-in validation modes covering the term and version dimensions
|
|
562
|
+
are proposed in [#634](https://github.com/rdfjs/N3.js/pull/634).
|
|
563
|
+
|
|
499
564
|
### Interface specifications
|
|
500
565
|
The N3.js submodules are compatible with the following [RDF.js](http://rdf.js.org) interfaces:
|
|
501
566
|
|