diff --git a/core/queryresultio/text/src/main/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLResultsTSVWriter.java b/core/queryresultio/text/src/main/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLResultsTSVWriter.java index 3bcbfc74a1a..9769a75766a 100644 --- a/core/queryresultio/text/src/main/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLResultsTSVWriter.java +++ b/core/queryresultio/text/src/main/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLResultsTSVWriter.java @@ -194,21 +194,15 @@ private void writeLiteral(Literal lit) throws IOException { // Append the literal's language writer.write("@"); writer.write(lit.getLanguage().get()); - } else if (!XSD.STRING.equals(datatype) || !xsdStringToPlainLiteral()) { - writer.write("\""); - writer.write(encoded); - writer.write("\""); - // Append the literal's datatype - writer.write("^^"); - writeURI(datatype); - } else if (!label.isEmpty() && encoded.equals(label) && label.charAt(0) != '<' && label.charAt(0) != '_' - && !label.matches("^[\\+\\-]?[\\d\\.].*")) { - // no need to include double quotes - writer.write(encoded); } else { writer.write("\""); writer.write(encoded); writer.write("\""); + // Append the literal's datatype if it's not xsd:string or if xsdStringToPlainLiteral is false + if (!XSD.STRING.equals(datatype) || !xsdStringToPlainLiteral()) { + writer.write("^^"); + writeURI(datatype); + } } } diff --git a/core/queryresultio/text/src/test/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLTSVCustomTest.java b/core/queryresultio/text/src/test/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLTSVCustomTest.java index 2dcfc8d3131..fcdd1192d3a 100644 --- a/core/queryresultio/text/src/test/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLTSVCustomTest.java +++ b/core/queryresultio/text/src/test/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLTSVCustomTest.java @@ -69,6 +69,24 @@ public void testSES2126QuotedLiteralIntegerAsStringImplicitType() throws Excepti assertEquals("?test\n\"1\"\n", result); } + @Test + public void testQuotedXSDStringLiteral() throws Exception { + List bindingNames = List.of("test"); + TupleQueryResult tqr = new IteratingTupleQueryResult(bindingNames, + List.of(new ListBindingSet(bindingNames, SimpleValueFactory.getInstance().createLiteral("example", XSD.STRING)))); + String result = writeTupleResult(tqr); + assertEquals("?test\n\"example\"\n", result); + } + + @Test + public void testQuotedXSDStringLiteralWithSpecialCharacters() throws Exception { + List bindingNames = List.of("test"); + TupleQueryResult tqr = new IteratingTupleQueryResult(bindingNames, + List.of(new ListBindingSet(bindingNames, SimpleValueFactory.getInstance().createLiteral("example\twith\nspecial\"characters", XSD.STRING)))); + String result = writeTupleResult(tqr); + assertEquals("?test\n\"example\\twith\\nspecial\\\"characters\"\n", result); + } + private String writeTupleResult(TupleQueryResult tqr) throws IOException, TupleQueryResultHandlerException, QueryEvaluationException { ByteArrayOutputStream output = new ByteArrayOutputStream();