From 69869b02c3c0fc792c2626ef1ece61616117596b Mon Sep 17 00:00:00 2001 From: Ata B Barzegar Date: Mon, 24 Aug 2026 02:30:38 +0300 Subject: [PATCH 1/4] feat: extract schema from VoID dataset descriptions - Add extract_schema_void() to query void:class, void:property, and void:linkPredicate from a SPARQL endpoint or rdflib file and populate the classes and properties fields of the schema. --- R/schema_void.R | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 R/schema_void.R diff --git a/R/schema_void.R b/R/schema_void.R new file mode 100644 index 0000000..cf8ac6d --- /dev/null +++ b/R/schema_void.R @@ -0,0 +1,35 @@ +#' @importFrom dplyr %>% filter transmute distinct +NULL + + +#' Extract a schema from a VoID dataset description,extracted information +#' +#' @param source A SPARQL endpoint URL or a parsed rdflib file. +#' @return A schema list, see [.empty_schema()]; only `classes` and +#' `properties` are populated. +#' @export +extract_schema_void <- function(source) { + schema <- .empty_schema() + + void_classes <- safe_query(source, ' + PREFIX void: + SELECT DISTINCT ?class WHERE { [] void:class ?class . }', expected_cols = "class") + + void_props <- safe_query(source, ' + PREFIX void: + SELECT DISTINCT ?prop WHERE { + { [] void:property ?prop } UNION { [] void:linkPredicate ?prop } + }', expected_cols = "prop") + + schema$classes <- void_classes %>% + filter(!is.na(class), nzchar(class)) %>% + transmute(uri = class, label = local_name(class)) %>% + distinct(uri, .keep_all = TRUE) + + schema$properties <- void_props %>% + filter(!is.na(prop), nzchar(prop)) %>% + transmute(property = prop, label = local_name(prop)) %>% + distinct(property, .keep_all = TRUE) + + schema +} From 3bf26a71f064d0e020e3c3f8fc29922adc1e0799 Mon Sep 17 00:00:00 2001 From: Ata B Barzegar Date: Mon, 24 Aug 2026 02:37:20 +0300 Subject: [PATCH 2/4] docs: add dplyr transmute to docs. --- NAMESPACE | 2 ++ man/extract_schema_void.Rd | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 man/extract_schema_void.Rd diff --git a/NAMESPACE b/NAMESPACE index 62ae34b..4548657 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,6 +5,7 @@ export(build_ont) export(extract_list_edges) export(extract_restrictions) export(extract_schema_owl) +export(extract_schema_void) export(local_name) export(make_display_list) export(namespace_of) @@ -19,3 +20,4 @@ importFrom(dplyr,distinct) importFrom(dplyr,filter) importFrom(dplyr,mutate) importFrom(dplyr,select) +importFrom(dplyr,transmute) diff --git a/man/extract_schema_void.Rd b/man/extract_schema_void.Rd new file mode 100644 index 0000000..dd8685a --- /dev/null +++ b/man/extract_schema_void.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/schema_void.R +\name{extract_schema_void} +\alias{extract_schema_void} +\title{Extract a schema from a VoID dataset description,extracted information} +\usage{ +extract_schema_void(source) +} +\arguments{ +\item{source}{A SPARQL endpoint URL or a parsed rdflib file.} +} +\value{ +A schema list, see \code{\link[=.empty_schema]{.empty_schema()}}; only \code{classes} and +\code{properties} are populated. +} +\description{ +Extract a schema from a VoID dataset description,extracted information +} From bab452e571580e4292518dbabbe57a8e1c2ae160 Mon Sep 17 00:00:00 2001 From: Ata B Barzegar Date: Mon, 24 Aug 2026 02:37:52 +0300 Subject: [PATCH 3/4] tests: add tests for schema_void.R file --- tests/testthat/test-schema_void.R | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 tests/testthat/test-schema_void.R diff --git a/tests/testthat/test-schema_void.R b/tests/testthat/test-schema_void.R new file mode 100644 index 0000000..a3eeb8a --- /dev/null +++ b/tests/testthat/test-schema_void.R @@ -0,0 +1,40 @@ +test_that("extract_schema_void reads void:class/property declarations", { + fake_sparql <- function(url, query, timeout = 60) { + if (grepl("void:class", query, fixed = TRUE)) { + data.frame(class = "http://ex.org/Dataset", stringsAsFactors = FALSE) + } else { + data.frame(prop = "http://purl.org/dc/terms/title", stringsAsFactors = FALSE) + } + } + testthat::local_mocked_bindings(sparql_query = fake_sparql) + + schema <- extract_schema_void("https://example.org/sparql") + + expect_equal(schema$classes$uri, "http://ex.org/Dataset") + expect_equal(schema$classes$label, "Dataset") + expect_equal(schema$properties$property, "http://purl.org/dc/terms/title") + expect_equal(schema$properties$label, "title") +}) + +test_that("extract_schema_void returns empty tables when there is no VoID data", { + testthat::local_mocked_bindings( + sparql_query = function(url, query, timeout = 60) data.frame() + ) + + schema <- extract_schema_void("https://example.org/sparql") + + expect_equal(nrow(schema$classes), 0) + expect_equal(names(schema$classes), c("uri", "label")) + expect_equal(nrow(schema$properties), 0) +}) + +test_that("extract_schema_void tolerates a failing endpoint", { + testthat::local_mocked_bindings( + sparql_query = function(url, query, timeout = 60) stop("timeout") + ) + + schema <- suppressWarnings(extract_schema_void("https://example.org/sparql")) + + expect_equal(nrow(schema$classes), 0) + expect_equal(nrow(schema$properties), 0) +}) From 92cdec30d39e95b72cfe7966ce48388286d3d0b9 Mon Sep 17 00:00:00 2001 From: Ata B Barzegar Date: Mon, 24 Aug 2026 02:45:53 +0300 Subject: [PATCH 4/4] docs: change empty_schema function documentation into inline code --- R/schema_void.R | 2 +- R/utils.R | 1 + man/extract_schema_void.Rd | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/R/schema_void.R b/R/schema_void.R index cf8ac6d..51216f8 100644 --- a/R/schema_void.R +++ b/R/schema_void.R @@ -5,7 +5,7 @@ NULL #' Extract a schema from a VoID dataset description,extracted information #' #' @param source A SPARQL endpoint URL or a parsed rdflib file. -#' @return A schema list, see [.empty_schema()]; only `classes` and +#' @return A schema list, see `.empty_schema()`; only `classes` and #' `properties` are populated. #' @export extract_schema_void <- function(source) { diff --git a/R/utils.R b/R/utils.R index bd2abac..4ade5ce 100644 --- a/R/utils.R +++ b/R/utils.R @@ -44,6 +44,7 @@ local_name <- function(uri) { normalize_scheme <- function(x) sub("^https://", "http://", x) + .empty_schema <- function() { list( classes = data.frame(uri = character(), label = character(), stringsAsFactors = FALSE), diff --git a/man/extract_schema_void.Rd b/man/extract_schema_void.Rd index dd8685a..673cccd 100644 --- a/man/extract_schema_void.Rd +++ b/man/extract_schema_void.Rd @@ -10,7 +10,7 @@ extract_schema_void(source) \item{source}{A SPARQL endpoint URL or a parsed rdflib file.} } \value{ -A schema list, see \code{\link[=.empty_schema]{.empty_schema()}}; only \code{classes} and +A schema list, see \code{.empty_schema()}; only \code{classes} and \code{properties} are populated. } \description{