Skip to content

Commit 03d76f2

Browse files
committed
Don't emit namespaces in XML Literals by default
This partially reverts 98d6ab5 and instead puts it behind a new parser option: `includeXmlNamespacesInLiterals` Related to w3c/rdf-tests#325
1 parent a023df1 commit 03d76f2

3 files changed

Lines changed: 85 additions & 12 deletions

File tree

README.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,17 +115,19 @@ Optionally, the following parameters can be set in the `RdfXmlParser` constructo
115115
* `iriValidationStrategy`: Allows to customize the used IRI validation strategy using the `IriValidationStrategy` enumeration. IRI validation is handled by [validate-iri.js](https://github.com/comunica/validate-iri.js/). _(Default: `IriValidationStrategy.Pragmatic`)_
116116
* `parseUnsupportedVersions`: If no error should be emitted on unsupported versions. _(Default: `false`)_
117117
* `version`: The version that was supplied as a media type parameter. _(Default: `undefined`)_
118+
* `includeXmlNamespacesInLiterals`: If namespaces from the current and parent tags should be included in XML Literals. _(Default: `false`)_
118119

119120
```javascript
120121
new RdfXmlParser({
121-
dataFactory: require('@rdfjs/data-model'),
122-
baseIRI: 'http://example.org/',
123-
defaultGraph: namedNode('http://example.org/graph'),
124-
strict: true,
125-
trackPosition: true,
126-
allowDuplicateRdfIds: true,
127-
validateUri: true,
128-
parseUnsupportedVersions: false,
122+
dataFactory: require('@rdfjs/data-model'),
123+
baseIRI: 'http://example.org/',
124+
defaultGraph: namedNode('http://example.org/graph'),
125+
strict: true,
126+
trackPosition: true,
127+
allowDuplicateRdfIds: true,
128+
validateUri: true,
129+
parseUnsupportedVersions: false,
130+
includeXmlNamespacesInLiterals: false,
129131
});
130132
```
131133

lib/RdfXmlParser.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
7171
private readonly iriValidationStrategy: IriValidationStrategy;
7272
private readonly parseUnsupportedVersions: boolean;
7373
private version: string | undefined;
74+
private readonly includeXmlNamespacesInLiterals: boolean;
7475

7576
private readonly activeTagStack: IActiveTag[] = [];
7677
private readonly nodeIds: Record<string, boolean> = {};
@@ -99,6 +100,7 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
99100
}
100101
this.parseUnsupportedVersions = Boolean(args?.parseUnsupportedVersions);
101102
this.version = args?.version;
103+
this.includeXmlNamespacesInLiterals = Boolean(args?.includeXmlNamespacesInLiterals);
102104

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

@@ -246,8 +248,10 @@ export class RdfXmlParser extends Transform implements RDF.Sink<EventEmitter, RD
246248
// Convert this tag to a string
247249
const tagName: string = tag.name;
248250
let attributes = '';
249-
for (const { key, value } of parentTag.namespaces || []) {
250-
attributes += ` ${key}="${value}"`;
251+
if (this.includeXmlNamespacesInLiterals) {
252+
for (const { key, value } of parentTag.namespaces || []) {
253+
attributes += ` ${key}="${value}"`;
254+
}
251255
}
252256
for (const attributeKey in tag.attributes) {
253257
attributes += ` ${attributeKey}="${tag.attributes[attributeKey].value}"`;
@@ -987,6 +991,11 @@ export interface IRdfXmlParserArgs {
987991
* The version that was supplied as a media type parameter.
988992
*/
989993
version?: string;
994+
/**
995+
* If namespaces from the current and parent tags should be included in XML Literals.
996+
* Defaults to false.
997+
*/
998+
includeXmlNamespacesInLiterals?: boolean;
990999
}
9911000

9921001
export interface IActiveTag {

test/RdfXmlParser-test.ts

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2276,14 +2276,38 @@ abc`)).rejects.toBeTruthy();
22762276
</rdf:RDF>`);
22772277
await expect(array)
22782278
.toBeRdfIsomorphic([
2279-
quad('http://example.org/item01', 'http://example.org/stuff/1.0/prop', '"\n <a:Box xmlns:a="http://example.org/a#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:ex="http://example.org/stuff/1.0/" required="true">\n' +
2279+
quad('http://example.org/item01', 'http://example.org/stuff/1.0/prop', '"\n <a:Box required="true">\n' +
22802280
' <a:widget size="10"></a:widget>\n' +
22812281
' <a:grommit id="23">abc</a:grommit>\n' +
22822282
' </a:Box>\n' +
22832283
' "^^http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral'),
22842284
]);
22852285
});
22862286

2287+
it('property element values with rdf:parseType="Literal" to literals with emit namespaces', async() => {
2288+
parser = new RdfXmlParser({ includeXmlNamespacesInLiterals: true });
2289+
const array = await parse(parser, `<?xml version="1.0"?>
2290+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
2291+
xmlns:ex="http://example.org/stuff/1.0/">
2292+
<rdf:Description rdf:about="http://example.org/item01">
2293+
<ex:prop rdf:parseType="Literal" xmlns:a="http://example.org/a#">
2294+
<a:Box required="true">
2295+
<a:widget size="10" />
2296+
<a:grommit id="23">abc</a:grommit>
2297+
</a:Box>
2298+
</ex:prop>
2299+
</rdf:Description>
2300+
</rdf:RDF>`);
2301+
await expect(array)
2302+
.toBeRdfIsomorphic([
2303+
quad('http://example.org/item01', 'http://example.org/stuff/1.0/prop', '"\n <a:Box xmlns:a="http://example.org/a#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:ex="http://example.org/stuff/1.0/" required="true">\n' +
2304+
' <a:widget size="10"></a:widget>\n' +
2305+
' <a:grommit id="23">abc</a:grommit>\n' +
2306+
' </a:Box>\n' +
2307+
' "^^http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral'),
2308+
]);
2309+
});
2310+
22872311
// 2.8
22882312
it('property element values with rdf:parseType="Literal" to literals without prefixes', async() => {
22892313
const array = await parse(parser, `<?xml version="1.0"?>
@@ -2297,11 +2321,30 @@ abc`)).rejects.toBeTruthy();
22972321
</rdf:RDF>`);
22982322
await expect(array)
22992323
.toBeRdfIsomorphic([
2300-
quad('http://example.org/item01', 'http://example.org/stuff/1.0/prop', '"\n <Box xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:ex="http://example.org/stuff/1.0/"></Box>\n' +
2324+
quad('http://example.org/item01', 'http://example.org/stuff/1.0/prop', '"\n <Box></Box>\n' +
23012325
' "^^http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral'),
23022326
]);
23032327
});
23042328

2329+
// 2.8
2330+
it(`property element values with rdf:parseType="Literal" to literals without prefixes with emit namespaces`, async() => {
2331+
parser = new RdfXmlParser({ includeXmlNamespacesInLiterals: true });
2332+
const array = await parse(parser, `<?xml version="1.0"?>
2333+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
2334+
xmlns:ex="http://example.org/stuff/1.0/">
2335+
<rdf:Description rdf:about="http://example.org/item01">
2336+
<ex:prop rdf:parseType="Literal">
2337+
<Box></Box>
2338+
</ex:prop>
2339+
</rdf:Description>
2340+
</rdf:RDF>`);
2341+
await expect(array)
2342+
.toBeRdfIsomorphic([
2343+
quad('http://example.org/item01', 'http://example.org/stuff/1.0/prop', '"\n <Box xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:ex="http://example.org/stuff/1.0/"></Box>\n' +
2344+
' "^^http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral'),
2345+
]);
2346+
});
2347+
23052348
it('and ignore unrecognized attributes on nodes', async() => {
23062349
const array = await parse(parser, `<?xml version="1.0"?>
23072350
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
@@ -2936,6 +2979,25 @@ abc`)).rejects.toBeTruthy();
29362979
<eg:prop rdf:annotation="http://example.com/triple1" rdf:parseType="Literal"><br /></eg:prop>
29372980
</rdf:Description>
29382981
2982+
</rdf:RDF>`);
2983+
await expect(array)
2984+
.toBeRdfIsomorphic([
2985+
quad('http://www.example.org/a', 'http://example.org/prop', '"<br></br>"^^http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral'),
2986+
quad('http://example.com/triple1', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#reifies', '<<http://www.example.org/a http://example.org/prop "<br></br>"^^http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral>>'),
2987+
]);
2988+
});
2989+
2990+
it('on property elements with rdf:annotation with literal parse type with emit namespaces', async() => {
2991+
parser = new RdfXmlParser({ includeXmlNamespacesInLiterals: true });
2992+
const array = await parse(parser, `<?xml version="1.0"?>
2993+
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
2994+
xmlns:eg="http://example.org/"
2995+
xml:base="http://example.com/">
2996+
2997+
<rdf:Description rdf:about="http://www.example.org/a">
2998+
<eg:prop rdf:annotation="http://example.com/triple1" rdf:parseType="Literal"><br /></eg:prop>
2999+
</rdf:Description>
3000+
29393001
</rdf:RDF>`);
29403002
await expect(array)
29413003
.toBeRdfIsomorphic([

0 commit comments

Comments
 (0)