Add RDF.Dataset.prefixes/1

This commit is contained in:
Marcel Otto 2020-10-28 11:51:00 +01:00
parent 29a860d969
commit 15002a0bbb
6 changed files with 52 additions and 24 deletions

View file

@ -9,6 +9,7 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
### Added
- `RDF.Dataset.prefixes/1` for getting an aggregated `RDF.PrefixMap` over all graphs
- `RDF.PrefixMap.put/3` for adding a prefix mapping and overwrite an existing one
### Changed

View file

@ -14,6 +14,12 @@ defmodule RDF.BlankNode.Increment do
alias RDF.BlankNode
@type state :: %{
optional(:prefix) => String.t(),
map: map,
counter: pos_integer
}
@impl BlankNode.Generator.Algorithm
def init(%{prefix: prefix} = opts) do
opts

View file

@ -17,7 +17,7 @@ defmodule RDF.Dataset do
@behaviour Access
alias RDF.{Graph, Description, IRI, Statement, PropertyMap}
alias RDF.{Graph, Description, IRI, Statement, PrefixMap, PropertyMap}
import RDF.Statement, only: [coerce_subject: 1, coerce_graph_name: 1]
import RDF.Utils
@ -853,6 +853,22 @@ defmodule RDF.Dataset do
def equal?(_, _), do: false
@doc """
Returns the aggregated prefixes of all graphs of `dataset` as a `RDF.PrefixMap`.
"""
@spec prefixes(t) :: PrefixMap.t() | nil
def prefixes(%__MODULE__{} = dataset) do
dataset
|> RDF.Dataset.graphs()
|> Enum.reduce(RDF.PrefixMap.new(), fn graph, prefixes ->
if graph.prefixes do
RDF.PrefixMap.merge!(prefixes, graph.prefixes, :ignore)
else
prefixes
end
end)
end
defp clear_metadata(%__MODULE__{} = dataset) do
%__MODULE__{
dataset

View file

@ -4,7 +4,7 @@ defmodule RDF.Turtle.Encoder do
use RDF.Serialization.Encoder
alias RDF.Turtle.Encoder.State
alias RDF.{BlankNode, Dataset, Description, Graph, IRI, XSD, Literal, LangString}
alias RDF.{BlankNode, Dataset, Description, Graph, IRI, XSD, Literal, LangString, PrefixMap}
@document_structure [
:base,
@ -36,14 +36,19 @@ defmodule RDF.Turtle.Encoder do
@ordered_properties MapSet.new(@predicate_order)
@impl RDF.Serialization.Encoder
@callback encode(Graph.t() | Dataset.t(), keyword | map) :: {:ok, String.t()} | {:error, any}
@spec encode(Graph.t() | Dataset.t(), keyword) :: {:ok, String.t()} | {:error, any}
def encode(data, opts \\ []) do
with base =
base =
Keyword.get(opts, :base, Keyword.get(opts, :base_iri))
|> base_iri(data)
|> init_base_iri(),
prefixes = Keyword.get(opts, :prefixes) |> prefixes(data) |> init_prefixes(),
{:ok, state} = State.start_link(data, base, prefixes) do
|> init_base_iri()
prefixes =
Keyword.get(opts, :prefixes)
|> prefixes(data)
|> init_prefixes()
with {:ok, state} = State.start_link(data, base, prefixes) do
try do
State.preprocess(state)
@ -74,7 +79,7 @@ defmodule RDF.Turtle.Encoder do
raise "unknown Turtle document element: #{inspect(element)}"
end
defp base_iri(nil, %RDF.Graph{base_iri: base_iri}) when not is_nil(base_iri), do: base_iri
defp base_iri(nil, %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: IRI.coerce_base(base_iri)
@ -91,19 +96,10 @@ defmodule RDF.Turtle.Encoder do
end
end
defp prefixes(nil, %RDF.Graph{prefixes: prefixes}) when not is_nil(prefixes), do: prefixes
defp prefixes(nil, %Graph{prefixes: prefixes}) when not is_nil(prefixes), do: prefixes
defp prefixes(nil, %RDF.Dataset{} = dataset) do
prefixes =
dataset
|> RDF.Dataset.graphs()
|> Enum.reduce(RDF.PrefixMap.new(), fn graph, prefixes ->
if graph.prefixes do
RDF.PrefixMap.merge!(prefixes, graph.prefixes, :ignore)
else
prefixes
end
end)
defp prefixes(nil, %Dataset{} = dataset) do
prefixes = Dataset.prefixes(dataset)
if Enum.empty?(prefixes) do
RDF.default_prefixes()
@ -113,7 +109,7 @@ defmodule RDF.Turtle.Encoder do
end
defp prefixes(nil, _), do: RDF.default_prefixes()
defp prefixes(prefixes, _), do: RDF.PrefixMap.new(prefixes)
defp prefixes(prefixes, _), do: PrefixMap.new(prefixes)
defp init_prefixes(prefixes) do
Enum.reduce(prefixes, %{}, fn {prefix, iri}, reverse ->

View file

@ -11,7 +11,8 @@ defmodule RDF.Test.Case do
using do
quote do
alias RDF.{Dataset, Graph, Description, IRI, XSD, PropertyMap}
alias RDF.{Dataset, Graph, Description, IRI, XSD, PrefixMap, PropertyMap}
alias RDF.NS.{RDFS, OWL}
alias unquote(__MODULE__).{EX, FOAF}
import RDF, only: [iri: 1, literal: 1, bnode: 1]

View file

@ -1757,6 +1757,14 @@ defmodule RDF.DatasetTest do
)
end
test "prefixes/1" do
assert Dataset.new()
|> Dataset.add(Graph.new(prefixes: [ex: EX, foo: RDFS]))
|> Dataset.add(Graph.new(name: EX.Graph, prefixes: [ex: EX, foo: OWL]))
|> Dataset.prefixes() ==
PrefixMap.new(ex: EX, foo: RDFS)
end
describe "Enumerable protocol" do
test "Enum.count" do
assert Enum.count(Dataset.new(name: EX.foo())) == 0