Skip to content

Commit 12caab4

Browse files
authored
Fix relative IRI resolution in RDF/XML (#300)
Thanks to straif from our community Discord for reporting this!
1 parent 0fb6892 commit 12caab4

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

src/main/scala/eu/neverblink/jelly/cli/util/jena/riot/RiotParserUtil.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package eu.neverblink.jelly.cli.util.jena.riot
22

33
import eu.neverblink.jelly.cli.command.rdf.util.RdfFormat
4+
import org.apache.jena.irix.IRIs
45
import org.apache.jena.riot.lang.LabelToNode
56
import org.apache.jena.riot.{RDFParser, RDFParserRegistry, RIOT}
67
import org.apache.jena.riot.system.StreamRDF
@@ -18,9 +19,14 @@ object RiotParserUtil:
1819
): Unit = {
1920
// Only really enable IRI resolution if the format supports it
2021
if resolveIris && format.supportsBaseIri then
21-
// Parser with full IRI resolution
22+
// Parser with full IRI resolution.
23+
// We set the base explicitly to the system base (the current working directory), which is
24+
// what Jena uses by default for stream-based Turtle/TriG parsing. Without this, readers that
25+
// do their own base handling (notably RDF/XML via ARP) receive a null base and fail to
26+
// resolve relative IRIs (e.g. "#foo"), throwing "Relative URI encountered".
2227
RDFParser.source(source)
2328
.lang(format.jenaLang)
29+
.base(IRIs.getBaseStr)
2430
.labelToNode(LabelToNode.createUseLabelAsGiven())
2531
.checking(false)
2632
.strict(false)

src/test/scala/eu/neverblink/jelly/cli/command/rdf/RdfToJellySpec.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import eu.neverblink.jelly.core.proto.v1.{LogicalStreamType, PhysicalStreamType,
88
import eu.neverblink.jelly.core.JellyOptions
99
import eu.neverblink.jelly.core.proto.google.v1 as google
1010
import eu.neverblink.jelly.core.utils.IoUtils
11+
import org.apache.jena.irix.IRIs
1112
import org.apache.jena.rdf.model.{Model, ModelFactory}
1213
import org.apache.jena.riot.{RDFLanguages, RDFParser}
1314
import org.apache.jena.sparql.core.DatasetGraphFactory
@@ -934,5 +935,26 @@ class RdfToJellySpec extends AnyWordSpec with TestFixtureHelper with Matchers:
934935
stmts.head.getPredicate.getURI should be("http://example.org/p")
935936
stmts.head.getObject.asResource().getURI should be("b")
936937
}
938+
939+
"IRI resolution enabled (default), input RDF/XML stream with relative IRIs" in
940+
withEmptyJellyFile { j =>
941+
val input =
942+
"""<?xml version="1.0" encoding="utf-8"?>
943+
|<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
944+
| <rdf:Description rdf:about="#relative">
945+
| <__g0:test.org xmlns:__g0="http://">test</__g0:test.org>
946+
| </rdf:Description>
947+
|</rdf:RDF>""".stripMargin
948+
RdfToJelly.setStdIn(ByteArrayInputStream(input.getBytes))
949+
RdfToJelly.runTestCommand(
950+
List("rdf", "to-jelly", "--in-format", RdfFormat.RdfXml.cliOptions.head, "--to", j),
951+
)
952+
val content = translateJellyBack(new FileInputStream(j))
953+
val stmts = content.listStatements().asScala.toSeq
954+
stmts.size should be(1)
955+
stmts.head.getSubject.getURI should be(s"${IRIs.getBaseStr}#relative")
956+
stmts.head.getPredicate.getURI should be("http://test.org")
957+
stmts.head.getObject.asLiteral().getString should be("test")
958+
}
937959
}
938960
}

0 commit comments

Comments
 (0)