From a40f09fc35ce4e14dcf770ae67ff5f99c1b9ced1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Mar 2026 19:42:51 +0000 Subject: [PATCH 1/2] Initial plan From 6bbb57fe7c1e3d7447c7065770d76c1da23c76cf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Mar 2026 19:53:35 +0000 Subject: [PATCH 2/2] Fix relative IRIs containing a forward slash and a colon Co-authored-by: rubensworks <440384+rubensworks@users.noreply.github.com> --- lib/RdfXmlParser.ts | 14 ++++++++++++++ test/RdfXmlParser-test.ts | 30 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/lib/RdfXmlParser.ts b/lib/RdfXmlParser.ts index a4d5b30..2a93b42 100644 --- a/lib/RdfXmlParser.ts +++ b/lib/RdfXmlParser.ts @@ -141,6 +141,20 @@ export class RdfXmlParser extends Transform implements RDF.Sink 0 && firstSlashPos >= 0 && firstSlashPos < colonPos) { + const encoded = value.split(':').join('\u0000'); + return this.uriToNamedNode(resolve(encoded, activeTag.baseIRI).split('\u0000').join(':')); + } return this.uriToNamedNode(resolve(value, activeTag.baseIRI)); } diff --git a/test/RdfXmlParser-test.ts b/test/RdfXmlParser-test.ts index 945e4b7..67957a4 100644 --- a/test/RdfXmlParser-test.ts +++ b/test/RdfXmlParser-test.ts @@ -211,6 +211,21 @@ abc`)).rejects.toBeTruthy(); expect(parser.valueToUri('xyz', { baseIRI: 'http://aa/././a' })) .toEqual(DF.namedNode('http://aa/xyz')); }); + + it('create a named node from a relative IRI with a slash before the colon', () => { + expect(parser.valueToUri('x/y:z', { baseIRI: 'http://base.org/path/' })) + .toEqual(DF.namedNode('http://base.org/path/x/y:z')); + }); + + it('create a named node from a relative IRI with a slash before the colon and no trailing slash on base', () => { + expect(parser.valueToUri('x/y:z', { baseIRI: 'http://base.org/path' })) + .toEqual(DF.namedNode('http://base.org/x/y:z')); + }); + + it('create a named node from a relative IRI with multiple colons after a slash', () => { + expect(parser.valueToUri('x/y:z:w', { baseIRI: 'http://base.org/path/' })) + .toEqual(DF.namedNode('http://base.org/path/x/y:z:w')); + }); }); describe('should error with line numbers', () => { @@ -2100,6 +2115,21 @@ abc`)).rejects.toBeTruthy(); ]); }); + // 2.14 - relative IRI with a colon after a slash + it('relative IRI containing a slash before a colon should be resolved against the base IRI', async () => { + const parserThis = new RdfXmlParser({ baseIRI: 'https://example.com/base/' }); + const array = await parse(parserThis, ` + + +`); + return expect(array) + .toBeRdfIsomorphic([ + quad('https://example.com/base/x/y:z', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', + 'https://example.com/default/C'), + ]); + }); + // 2.15 it('rdf:li properties', async () => { const array = await parse(parser, `