-
Notifications
You must be signed in to change notification settings - Fork 177
Description
Current Behavior
When serializing an RDF list created using RDFCollections.asRDF() with TurtleWriter the first segment of the list is not properly inlined as it is not recognized as a well-formed list.
The result looks as this:
@prefix ex: <http://example.com/ns#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
ex:Cities ex:list [ a rdf:List;
rdf:first ex:NewYork;
rdf:rest (ex:Rio ex:Tokyo)
] .
Please notice the first part with explicit rdf:first and rdf:rest statements instead of the inlining of the list, which is done for the last two segments of the list.
This is caused by org.eclipse.rdf4j.rio.turtle.TurtleWriter.isWellFormedCollection() not recognizing the rdf:type rdf:List type statement for the first part of the list segment which is generated in RDFCollections.asRDF() (or more specifically in org.eclipse.rdf4j.model.util.RDFCollections.consumeCollection(Iterable<?>, Resource, Consumer<Statement>, ValueFactory, Resource...)).
A simple solution would be to adjust org.eclipse.rdf4j.rio.turtle.TurtleWriter.isWellFormedCollection() to recognize and accept that statement when checking for additional statements within the list.
Expected Behavior
The proper visualization of the list would instead look like this:
@prefix ex: <http://example.com/ns#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
ex:Cities ex:list (ex:NewYork ex:Rio ex:Tokyo) .
Steps To Reproduce
This test case reproduces the behavior:
package com.metaphacts.services.ontologies;
import static org.junit.Assert.assertEquals;
import java.io.StringWriter;
import java.util.List;
import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.impl.TreeModel;
import org.eclipse.rdf4j.model.util.RDFCollections;
import org.eclipse.rdf4j.model.util.Values;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.rio.RDFFormat;
import org.eclipse.rdf4j.rio.Rio;
import org.eclipse.rdf4j.rio.WriterConfig;
import org.eclipse.rdf4j.rio.helpers.BasicWriterSettings;
import org.junit.Test;
public class RDFCollectionsTest {
@Test
public void testBNodeValuesInList() throws Exception {
final String ns = "http://example.com/ns#";
IRI newyork = Values.iri(ns, "NewYork");
IRI rio = Values.iri(ns, "Rio");
IRI tokyo = Values.iri(ns, "Tokyo");
IRI cities = Values.iri(ns, "Cities");
IRI exList = Values.iri(ns, "list");
BNode listHead = Values.bnode("n1");
Model data = new TreeModel();
data.setNamespace("ex", ns);
data.setNamespace("rdf", RDF.NAMESPACE);
RDFCollections.asRDF(List.of(newyork, rio, tokyo), listHead, data);
data.add(cities, exList, listHead);
String expected = "" +
"@prefix ex: <http://example.com/ns#> .\n" +
"@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n" +
"\n" +
"ex:Cities ex:list (ex:NewYork ex:Rio ex:Tokyo) .\n";
StringWriter stringWriter = new StringWriter();
WriterConfig config = new WriterConfig();
config.set(BasicWriterSettings.INLINE_BLANK_NODES, true);
config.set(BasicWriterSettings.PRETTY_PRINT, true);
Rio.write(data, stringWriter, RDFFormat.TURTLE, config);
String actual = stringWriter.toString();
// System.out.println("### ACTUAL ###");
// System.out.println(actual);
// System.out.println("#################\n");
// System.out.println("### EXPECTED ###");
// System.out.println(expected);
// System.out.println("#################\n");
assertEquals("The visual representation should be a proper list for all elements", expected, actual);
}
}
Adding this line before serializing the model as string makes the test work, but the fix should not remove that statement but rather recognize and accept it.
// deleting the type statement in the list would make it work
// [ a rdf:List ]
// data.remove(listHead, RDF.TYPE, RDF.LIST);
Version
3.7.4 (and likely earlier versions as well)
Are you interested in contributing a solution yourself?
Perhaps?
Anything else?
No response