Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniFdezAlvarez committed Aug 27, 2024
2 parents 9338431 + b212edd commit c8c6442
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 40 deletions.
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ def read(file_path):
setup(
name = 'shexer',
packages = find_packages(exclude=["*.local_code.*"]), # this must be the same as the name above
version = '2.5.4',
version = '2.5.5',
description = 'Automatic schema extraction for RDF graphs',
author = 'Daniel Fernandez-Alvarez',
author_email = '[email protected]',
url = 'https://github.com/DaniFdezAlvarez/shexer',
download_url = 'https://github.com/DaniFdezAlvarez/shexer/archive/2.5.4.tar.gz',
download_url = 'https://github.com/DaniFdezAlvarez/shexer/archive/2.5.5.tar.gz',
keywords = ['testing', 'shexer', 'shexerp3', "rdf", "shex", "shacl", "schema"],
long_description = read('README.md'),
long_description_content_type='text/markdown',
Expand Down
53 changes: 35 additions & 18 deletions shexer/io/shex/formater/shex_serializer.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import re

from shexer.core.profiling.class_profiler import RDF_TYPE_STR

from shexer.model.property import Property
Expand All @@ -11,8 +13,10 @@
from wlighter import SHEXC_FORMAT

_MODES_REPORT_INSTANCES = [ABSOLUTE_INSTANCES, MIXED_INSTANCES]
_EXAMPLE_CONSTRAINT_TEMPLATE = "# Node constraint example: '{}'"
_EXAMPLE_SHAPE_TEMPLATE = "{} Instance example: '{}'"
_EXAMPLE_CONSTRAINT_TEMPLATE = '// rdfs:comment {} ;'
_EXAMPLE_INSTANCE_TEMPLATE = " // rdfs:comment {}"

_INIT_URI_PATTERN = re.compile("http[s]?\://")


class ShexSerializer(object):
Expand Down Expand Up @@ -85,10 +89,9 @@ def _serialize_empty_namespace(self):

def _serialize_shape(self, a_shape):
self._serialize_shape_name(a_shape)
# self._serialize_example(a_shape)
self._serialize_opening_of_rules()
self._serialize_shape_rules(a_shape)
self._serialize_closure_of_rule()
self._serialize_closure_of_rules(a_shape)
self._serialize_shape_gap()

def _flush(self):
Expand Down Expand Up @@ -147,13 +150,32 @@ def _add_statement_examples(self, a_shape):
for a_statement in a_shape.yield_statements():
if a_statement.st_property != self._instantiation_property_str:
comment = _EXAMPLE_CONSTRAINT_TEMPLATE.format(
self._get_node_constraint_example_no_inverse(a_shape, a_statement) if not self._inverse_paths
else self._get_node_constraint_example_inverse(a_shape, a_statement)
self._turn_str_comment_into_proper_rdf(
self._get_node_constraint_example_no_inverse(a_shape, a_statement) if not self._inverse_paths
else self._get_node_constraint_example_inverse(a_shape, a_statement)
)
)

a_statement.add_comment(comment, insert_first=True)


def _turn_str_comment_into_proper_rdf(self, str_object_to_transform):
"""
If it's a whole prefixed URI, return it as it is.
If it is a literal, surround it with quotes.
If it starts with http(s)://, surround it with corners.
"""

if " " not in str_object_to_transform and "".count(":") == 1:
return str_object_to_transform
elif _INIT_URI_PATTERN.match(str_object_to_transform):
prefixed = prefixize_uri_if_possible(str_object_to_transform, namespaces_prefix_dict=self._namespaces_dict, corners=False)
if prefixed == str_object_to_transform:
return "<"+str_object_to_transform+">"
else:
return prefixed
else:
return '"' + str_object_to_transform + '"'

def _get_node_constraint_example_no_inverse(self, shape, statement):
candidate = self._shape_example_features.get_constraint_example(shape_id=shape.class_uri,
Expand Down Expand Up @@ -181,22 +203,17 @@ def _serialize_shape_name(self, a_shape):
prefixize_shape_name_if_possible(a_shape_name=a_shape.name,
namespaces_prefix_dict=self._namespaces_dict) +
self._minimal_iri(a_shape=a_shape) +
self._instance_count(a_shape) +
self._serialize_example(a_shape)
self._instance_count(a_shape)
)

def _serialize_example(self, a_shape):
if self._examples_mode not in [ALL_EXAMPLES, SHAPE_EXAMPLES]:
return ""
return _EXAMPLE_SHAPE_TEMPLATE.format(
" " if self._instances_report_mode in _MODES_REPORT_INSTANCES and not self._disable_comments else " #",
self._shape_example_features.shape_example(shape_id=a_shape.class_uri))
# self._write_line(
# a_line=_EXAMPLE_SHAPE_TEMPLATE.format(
# self._shape_example_features.shape_example(shape_id=a_shape.class_uri)),
# indent_level=2)
candidate = self._shape_example_features.shape_example(shape_id=a_shape.class_uri)
prefixed = prefixize_uri_if_possible(candidate, namespaces_prefix_dict=self._namespaces_dict, corners=False)
return _EXAMPLE_INSTANCE_TEMPLATE.format( prefixed if prefixed != candidate else f'<{candidate}>')


# self._instances_report_mode in _MODES_REPORT_INSTANCES and not self._disable_comments


def _minimal_iri(self, a_shape):
Expand All @@ -213,8 +230,8 @@ def _instance_count(self, a_shape):
def _serialize_opening_of_rules(self):
self._write_line("{")

def _serialize_closure_of_rule(self):
self._write_line("}")
def _serialize_closure_of_rules(self, a_shape):
self._write_line("}" + self._serialize_example(a_shape=a_shape))

def _serialize_shape_gap(self):
self._write_line("")
Expand Down
3 changes: 1 addition & 2 deletions shexer/model/shape.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

class Shape(object):

def __init__(self, name, class_uri, statements, n_instances, iri_pattern=None):
def __init__(self, name, class_uri, statements, n_instances):
self._name = name
self._class_uri = class_uri
self._statements = statements if statements is not None else []
Expand All @@ -12,7 +12,6 @@ def __init__(self, name, class_uri, statements, n_instances, iri_pattern=None):
self._sorting_callback = lambda x: x.probability
self._n_direct_statements = self._count_direct_statements(statements)
self._n_inverse_statements = len(statements) - self._n_direct_statements
# self._iri_pattern = iri_pattern

@property
def name(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ PREFIX : <http://weso.es/shapes/>
{
rdf:type [foaf:Person] ; # 100.0 %
foaf:age xsd:integer ?;
# Node constraint example: '22'
// rdfs:comment "22" ;
# 80.0 % obj: xsd:integer. Cardinality: {1}
foaf:name xsd:string ?;
# Node constraint example: 'Jimmy'
// rdfs:comment "Jimmy" ;
# 60.0 % obj: xsd:string. Cardinality: {1}
foaf:familyName xsd:string ?;
# Node constraint example: 'Jones'
// rdfs:comment "Jones" ;
# 40.0 % obj: xsd:string. Cardinality: {1}
foaf:knows @:Person ?
# Node constraint example: 'ex:Bella'
// rdfs:comment "ex:Bella" ;
# 20.0 % obj: @:Person. Cardinality: {1}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ PREFIX : <http://weso.es/shapes/>
{
rdf:type [foaf:Person] ; # 100.0 %
foaf:age xsd:integer ?;
# Node constraint example: '22'
// rdfs:comment "22" ;
# 80.0 % obj: xsd:integer. Cardinality: {1}
foaf:name xsd:string ?;
# Node constraint example: 'Jimmy'
// rdfs:comment "Jimmy" ;
# 60.0 % obj: xsd:string. Cardinality: {1}
foaf:familyName xsd:string ?;
# Node constraint example: 'Jones'
// rdfs:comment "Jones" ;
# 40.0 % obj: xsd:string. Cardinality: {1}
foaf:knows @:Person ?;
# Node constraint example: 'http://example.org/Bella'
// rdfs:comment ex:Bella ;
# 20.0 % obj: @:Person. Cardinality: {1}
^ foaf:knows @:Person ?
# Node constraint example: 'http://example.org/Jimmy'
// rdfs:comment ex:Jimmy ;
# 20.0 % obj: @:Person. Cardinality: {1}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX : <http://weso.es/shapes/>

:Person # Instance example: 'http://example.org/Jimmy'
:Person
{
rdf:type [foaf:Person] # 100.0 %
}
} // rdfs:comment ex:Jimmy
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX : <http://weso.es/shapes/>

:Person # 1 instance. Instance example: 'http://example.org/Jimmy'
:Person # 1 instance.
{
rdf:type [foaf:Person] # 1 instance.
}
} // rdfs:comment ex:Jimmy
11 changes: 6 additions & 5 deletions test/test_examples_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ def test_all_examples_with_instance_stats(self):
inverse_paths=False,
instances_report_mode=ABSOLUTE_INSTANCES)
str_result = shaper.shex_graph(string_output=True)
# print(str_result)
self.assertTrue("# Node constraint example: '22'" in str_result)
self.assertTrue(":Person # 1 instance. Instance example: 'http://example.org/Jimmy'" in str_result)
self.assertTrue('// rdfs:comment "22" ;' in str_result)
self.assertTrue(":Person # 1 instance." in str_result)
self.assertTrue("} // rdfs:comment ex:Jimmy" in str_result)

def test_all_examples_no_instance_stats(self):
shaper = Shaper(
Expand All @@ -103,8 +103,9 @@ def test_all_examples_no_instance_stats(self):
examples_mode=ALL_EXAMPLES,
inverse_paths=False)
str_result = shaper.shex_graph(string_output=True)
self.assertTrue("# Node constraint example: '22'" in str_result)
self.assertTrue(":Person # Instance example: 'http://example.org/Jimmy'" in str_result)
self.assertTrue('// rdfs:comment "22" ;' in str_result)
self.assertTrue("} // rdfs:comment ex:Jimmy" in str_result)
self.assertFalse(":Person # 1 instance." in str_result)



0 comments on commit c8c6442

Please sign in to comment.