Use RDF.default_base_iri in Turtle encoder and decoder

This commit is contained in:
Marcel Otto 2019-08-04 00:13:13 +02:00
parent 58d21a3405
commit 5f855de58c
6 changed files with 19 additions and 25 deletions

View file

@ -18,8 +18,12 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
### Changed
- `RDF.Turtle.Decoder` saves the base IRI in the `RDF.Graph` now
- `RDF.Turtle.Encoder` now takes the base IRI to be serialized from the graph when
no base IRI is given with the `base` option or its new alias `base_iri`
- `RDF.Turtle.Encoder` now takes the base IRI to be used during serialization in
the following order of precedence:
- from the the `base` option or its new alias `base_iri`
- from the `base_iri` field of the given graph
- from the `RDF.default_base_iri` returning the one from the application
configuration
[Compare v0.6.1...HEAD](https://github.com/marcelotto/rdf-ex/compare/v0.6.1...HEAD)

View file

@ -40,6 +40,8 @@ defmodule RDF do
alias RDF.{IRI, Namespace, Literal, BlankNode, Triple, Quad,
Description, Graph, Dataset, PrefixMap}
defdelegate default_base_iri(), to: RDF.IRI, as: :default_base
@standard_prefixes PrefixMap.new(
xsd: IRI.new("http://www.w3.org/2001/XMLSchema#"),

View file

@ -27,7 +27,7 @@ defmodule RDF.IRI do
@scheme_regex Regex.recompile!(~r/^([a-z][a-z0-9\+\-\.]*):/i)
@doc """
The default base IRI to be used when reading a serialization and no `base` option is provided.
The default base IRI to be used when reading a serialization and no `base_iri` option is provided.
The value can be set via the `default_base_iri` configuration. For example:

View file

@ -2,15 +2,11 @@ defmodule RDF.Serialization.Reader do
@moduledoc """
General functions for reading a `RDF.Graph` or `RDF.Dataset` from a serialization file or encoded-string.
If no base IRI is provided with the `base` option on any of these functions,
the `RDF.IRI.default_base/0` is used.
You probably won't use these functions directly, but instead use the automatically
generated functions with same name on a `RDF.Serialization.Format`, which implicitly
use the proper `RDF.Serialization.Decoder` module.
"""
@doc """
Reads and decodes a serialized graph or dataset from a string.
@ -18,7 +14,7 @@ defmodule RDF.Serialization.Reader do
dataset, or `{:error, reason}` if an error occurs.
"""
def read_string(decoder, content, opts \\ []) do
decoder.decode(content, with_base(opts))
decoder.decode(content, opts)
end
@doc """
@ -27,7 +23,7 @@ defmodule RDF.Serialization.Reader do
As opposed to `read_string`, it raises an exception if an error occurs.
"""
def read_string!(decoder, content, opts \\ []) do
decoder.decode!(content, with_base(opts))
decoder.decode!(content, opts)
end
@doc """
@ -38,7 +34,7 @@ defmodule RDF.Serialization.Reader do
"""
def read_file(decoder, file, opts \\ []) do
case File.read(file) do
{:ok, content} -> read_string(decoder, content, with_base(opts))
{:ok, content} -> read_string(decoder, content, opts)
{:error, reason} -> {:error, reason}
end
end
@ -50,16 +46,7 @@ defmodule RDF.Serialization.Reader do
"""
def read_file!(decoder, file, opts \\ []) do
with content = File.read!(file) do
read_string!(decoder, content, with_base(opts))
read_string!(decoder, content, opts)
end
end
defp with_base(opts) do
cond do
Keyword.has_key?(opts, :base) -> opts
base = RDF.IRI.default_base() -> Keyword.put(opts, :base, base)
true -> opts
end
end
end

View file

@ -33,8 +33,8 @@ defmodule RDF.Turtle.Decoder do
def decode(content, opts) do
with {:ok, tokens, _} <- tokenize(content),
{:ok, ast} <- parse(tokens),
base = Map.get(opts, :base) do
build_graph(ast, base && RDF.iri(base))
base_iri = Map.get(opts, :base, Map.get(opts, :base_iri, RDF.default_base_iri())) do
build_graph(ast, base_iri && RDF.iri(base_iri))
else
{:error, {error_line, :turtle_lexer, error_descriptor}, _error_line_again} ->
{:error, "Turtle scanner error on line #{error_line}: #{error_description error_descriptor}"}
@ -48,9 +48,9 @@ defmodule RDF.Turtle.Decoder do
def parse([]), do: {:ok, []}
def parse(tokens), do: tokens |> :turtle_parser.parse
defp build_graph(ast, base) do
defp build_graph(ast, base_iri) do
{graph, %State{namespaces: namespaces, base_iri: base_iri}} =
Enum.reduce ast, {RDF.Graph.new, %State{base_iri: base}}, fn
Enum.reduce ast, {RDF.Graph.new, %State{base_iri: base_iri}}, fn
{:triples, triples_ast}, {graph, state} ->
with {statements, state} = triples(triples_ast, state) do
{RDF.Graph.add(graph, statements), state}

View file

@ -47,7 +47,8 @@ defmodule RDF.Turtle.Encoder do
end
end
defp base_iri(nil, %RDF.Graph{base_iri: base_iri}), do: base_iri
defp base_iri(nil, %RDF.Graph{base_iri: base_iri}) when not is_nil(base_iri), do: base_iri
defp base_iri(nil, _), do: RDF.default_base_iri()
defp base_iri(base_iri, _), do: RDF.iri(base_iri)
defp init_base_iri(nil), do: nil