Use base URI in URIs of @prefix and @base directives

This commit is contained in:
Marcel Otto 2017-07-10 01:41:36 +02:00
parent d1ef0d1fb3
commit 529714ec1c
2 changed files with 40 additions and 9 deletions

View file

@ -63,11 +63,26 @@ defmodule RDF.Turtle.Decoder do
end
defp directive({:prefix, {:prefix_ns, _, ns}, iri}, state) do
State.add_namespace(state, ns, iri)
if RDF.URI.Helper.absolute_iri?(iri) do
State.add_namespace(state, ns, iri)
else
with absolute_uri = RDF.URI.Helper.absolute_iri(iri, state.base_uri) do
State.add_namespace(state, ns, URI.to_string(absolute_uri))
end
end
end
defp directive({:base, uri}, state) do
%State{state | base_uri: RDF.uri(uri)}
defp directive({:base, uri}, %State{base_uri: base_uri} = state) do
cond do
RDF.URI.Helper.absolute_iri?(uri) ->
%State{state | base_uri: RDF.uri(uri)}
base_uri != nil ->
with absolute_uri = RDF.URI.Helper.absolute_iri(uri, base_uri) do
%State{state | base_uri: absolute_uri}
end
true ->
raise "Could not resolve resolve relative IRI '#{uri}', no base uri provided"
end
end

View file

@ -17,13 +17,29 @@ defmodule RDF.URI.Helper do
characters are treated in URI references, per [section 6.5 of RFC3987](http://tools.ietf.org/html/rfc3987#section-6.5)
"""
def absolute_iri(value, base_iri) do
case URI.parse(value) do
# absolute?
uri = %URI{scheme: scheme} when not is_nil(scheme) -> uri
# relative
_ when is_nil(base_iri) -> nil
_ -> URI.merge(base_iri, value)
uri =
case URI.parse(value) do
# absolute?
uri = %URI{scheme: scheme} when not is_nil(scheme) -> uri
# relative
_ when is_nil(base_iri) -> nil
_ -> URI.merge(base_iri, value)
end
if String.ends_with?(value, "#") do
%URI{uri | fragment: ""}
else
uri
end
end
@doc """
Checks if the given value is an absolute IRI.
An absolute IRI is defined in [RFC3987](http://www.ietf.org/rfc/rfc3987.txt)
containing a scheme along with a path and optional query and fragment segments.
see <https://www.w3.org/TR/json-ld-api/#dfn-absolute-iri>
"""
def absolute_iri?(value), do: RDF.uri?(value)
end