Skip to content

Commit d51d0fd

Browse files
authored
Add option to disable URI validation, Closes #61
1 parent e52bf1f commit d51d0fd

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ Optionally, the following parameters can be set in the `RdfXmlParser` constructo
9595
* `strict`: If the internal SAX parser should parse XML in strict mode, and error if it is invalid. _(Default: `false`)_
9696
* `trackPosition`: If the internal position (line, column) should be tracked an emitted in error messages. _(Default: `false`)_
9797
* `allowDuplicateRdfIds`: By default [multiple occurrences of the same `rdf:ID` value are not allowed](https://www.w3.org/TR/rdf-syntax-grammar/#section-Syntax-ID-xml-base). By setting this option to `true`, this uniqueness check can be disabled. _(Default: `false`)_
98+
* `validateUri`: By default, the parser validates each URI. _(Default: `true`)_
9899

99100
```javascript
100101
new RdfXmlParser({
@@ -104,6 +105,7 @@ new RdfXmlParser({
104105
strict: true,
105106
trackPosition: true,
106107
allowDuplicateRdfIds: true,
108+
validateUri: true,
107109
});
108110
```
109111

lib/RdfXmlParser.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
5050
private readonly defaultGraph?: RDF.Quad_Graph;
5151
private readonly allowDuplicateRdfIds?: boolean;
5252
private readonly saxParser: SaxesParser;
53+
private readonly validateUri: boolean;
5354

5455
private readonly activeTagStack: IActiveTag[] = [];
5556
private readonly nodeIds: {[id: string]: boolean} = {};
@@ -70,6 +71,9 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
7071
if (!this.defaultGraph) {
7172
this.defaultGraph = this.dataFactory.defaultGraph();
7273
}
74+
if (this.validateUri !== false) {
75+
this.validateUri = true;
76+
}
7377

7478
this.saxParser = new SaxesParser({ xmlns: true, position: this.trackPosition });
7579

@@ -85,6 +89,10 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
8589
return RdfXmlParser.IRI_REGEX.test(iri);
8690
}
8791

92+
get uriValidationEnabled() {
93+
return this.validateUri;
94+
}
95+
8896
/**
8997
* Parses the given text stream into a quad stream.
9098
* @param {NodeJS.EventEmitter} stream A text stream.
@@ -140,7 +148,7 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
140148
*/
141149
public uriToNamedNode(uri: string): RDF.NamedNode {
142150
// Validate URI
143-
if (!RdfXmlParser.isValidIri(uri)) {
151+
if (this.uriValidationEnabled && !RdfXmlParser.isValidIri(uri)) {
144152
throw this.newParseError(`Invalid URI: ${uri}`);
145153
}
146154
return this.dataFactory.namedNode(uri);
@@ -688,6 +696,11 @@ export interface IRdfXmlParserArgs {
688696
* By setting this option to `true`, this uniqueness check can be disabled.
689697
*/
690698
allowDuplicateRdfIds?: boolean;
699+
/**
700+
* Enables validation of all URIs. Will throw an Error in case of an invalid URI.
701+
* By default, it is equal to true.
702+
*/
703+
validateUri?: boolean;
691704
}
692705

693706
export interface IActiveTag {

test/RdfXmlParser-test.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ describe('RdfXmlParser', () => {
2525
expect((<any> instance).baseIRI).toBe('');
2626
expect((<any> instance).defaultGraph).toBe(DF.defaultGraph());
2727
expect((<any> instance).saxParser).toBeInstanceOf(SaxesParser);
28+
expect((<any> instance).validateUri).toBeTruthy();
29+
expect(instance.uriValidationEnabled).toBeTruthy();
2830
});
2931

3032
it('should be constructable with empty args', () => {
@@ -34,6 +36,8 @@ describe('RdfXmlParser', () => {
3436
expect((<any> instance).baseIRI).toBe('');
3537
expect((<any> instance).defaultGraph).toBe(DF.defaultGraph());
3638
expect((<any> instance).saxParser).toBeInstanceOf(SaxesParser);
39+
expect((<any> instance).validateUri).toBeTruthy();
40+
expect(instance.uriValidationEnabled).toBeTruthy();
3741
});
3842

3943
it('should be constructable with args with a custom data factory', () => {
@@ -76,6 +80,13 @@ describe('RdfXmlParser', () => {
7680
expect((<any> instance).saxParser).toBeInstanceOf(SaxesParser);
7781
});
7882

83+
it('should be constructible with args with disabled validateUri', () => {
84+
const instance = new RdfXmlParser({ validateUri: false });
85+
expect(instance).toBeInstanceOf(RdfXmlParser);
86+
expect((<any> instance).validateUri).toBeFalsy();
87+
expect(instance.uriValidationEnabled).toBeFalsy();
88+
});
89+
7990
describe('#isValidIri', () => {
8091
it('should be false for null', async () => {
8192
expect(RdfXmlParser.isValidIri(null)).toBeFalsy();
@@ -111,7 +122,6 @@ describe('RdfXmlParser', () => {
111122
});
112123

113124
describe('a default instance', () => {
114-
115125
let parser: any;
116126

117127
beforeEach(() => {
@@ -2366,6 +2376,27 @@ abc`)).rejects.toBeTruthy();
23662376
});
23672377
});
23682378

2379+
describe('an instance with disabled URI validation', () => {
2380+
let parser: any;
2381+
2382+
beforeEach(() => {
2383+
parser = new RdfXmlParser({ validateUri: false });
2384+
});
2385+
2386+
describe('#valueToUri', () => {
2387+
2388+
it('ignore a URI with an invalid scheme', () => {
2389+
expect(() => parser.valueToUri('%https://example.com/', {}))
2390+
.not.toThrow(new Error('Invalid URI: %https://example.com/'));
2391+
});
2392+
2393+
it('ignore a URI with an invalid character', () => {
2394+
expect(() => parser.valueToUri('https://example.com/<', {}))
2395+
.not.toThrow(new Error('Invalid URI: https://example.com/<'));
2396+
});
2397+
});
2398+
});
2399+
23692400
describe('#import', () => {
23702401
let parser: any;
23712402

0 commit comments

Comments
 (0)