n3 2.2.10 → 2.2.12

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 CHANGED
@@ -496,6 +496,62 @@ and allows a mixture of different syntaxes.
496
496
  Pass a `format` option to the constructor with the name or MIME type of a format
497
497
  for strict, fault-intolerant behavior.
498
498
 
499
+ ### Validation
500
+ The **parser** validates the _syntax_ of the selected format's grammar, with the following exceptions:
501
+ - IRIs are not checked for full [RFC 3987](https://www.rfc-editor.org/rfc/rfc3987) well-formedness
502
+ (`<http://example.org/%ZZ>` parses),
503
+ and relative IRIs remain relative when no `baseIRI` option is given;
504
+ - literal values are not checked against their datatype (`"abc"^^xsd:integer` parses);
505
+ - language tags are checked against the grammar, not against [BCP 47](https://www.rfc-editor.org/rfc/rfc5646);
506
+
507
+ The **writer** trusts the terms it is given. Quads constructed with invalid term values are serialized as-is and can yield invalid documents.
508
+
509
+ Therefore, term validation should be done post-parsing to ensure that valid RDF terms should be produced.
510
+
511
+ 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.
512
+
513
+ 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.
514
+ ```JavaScript
515
+ const { Transform } = require('stream');
516
+ const { validateIri, IriValidationStrategy } = require('validate-iri');
517
+ const { validators } = require('rdf-validate-datatype');
518
+ const { parse: parseLanguageTag } = require('bcp-47');
519
+
520
+ function validateTerm(term) {
521
+ switch (term.termType) {
522
+ case 'NamedNode': // RDF requires absolute IRIs
523
+ return validateIri(term.value, IriValidationStrategy.Strict) || null;
524
+ case 'Literal':
525
+ if (term.language) {
526
+ let invalid = false;
527
+ parseLanguageTag(term.language, { warning: () => { invalid = true; } });
528
+ return invalid ? new Error(`Invalid language tag "${term.language}"`) : null;
529
+ }
530
+ const validate = validators.find(term.datatype);
531
+ return validate && !validate(term.value)
532
+ ? new Error(`Invalid value "${term.value}" for datatype ${term.datatype.value}`)
533
+ : null; // unknown datatypes cannot be judged
534
+ default:
535
+ return null;
536
+ }
537
+ }
538
+
539
+ const quadStream = fs.createReadStream('data.ttl')
540
+ .pipe(new N3.StreamParser())
541
+ .pipe(new Transform({
542
+ objectMode: true,
543
+ transform(quad, encoding, done) {
544
+ const error = validateTerm(quad.subject) || validateTerm(quad.predicate) ||
545
+ validateTerm(quad.object) || validateTerm(quad.graph);
546
+ done(error, error ? undefined : quad); // or: skip/collect instead of failing
547
+ },
548
+ }));
549
+ ```
550
+
551
+
552
+ Parser-level opt-in validation modes covering the term and version dimensions
553
+ are proposed in [#634](https://github.com/rdfjs/N3.js/pull/634).
554
+
499
555
  ### Interface specifications
500
556
  The N3.js submodules are compatible with the following [RDF.js](http://rdf.js.org) interfaces:
501
557