Skip to content

Commit 050f30a

Browse files
committed
support extraction from sh:or
1 parent 69ccc09 commit 050f30a

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

buildingmotif/utils.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import pyshacl # type: ignore
1111
from rdflib import BNode, Graph, Literal, URIRef
12+
from rdflib.collection import Collection
1213
from rdflib.compare import _TripleCanonicalizer
1314
from rdflib.paths import ZeroOrOne
1415
from rdflib.term import Node
@@ -380,6 +381,22 @@ def _gather(predicate):
380381
if pvalue:
381382
body.add((focus_param, property_path, pvalue))
382383

384+
for or_list in shape_graph.objects(shape_node, SH["or"]):
385+
try:
386+
options = list(Collection(shape_graph, or_list))
387+
except Exception:
388+
options = []
389+
if not options:
390+
continue
391+
chosen = options[0]
392+
if isinstance(chosen, URIRef):
393+
if is_nodeshape(chosen):
394+
process_shape(chosen, focus_param)
395+
else:
396+
body.add((focus_param, RDF.type, chosen))
397+
elif isinstance(chosen, BNode):
398+
process_shape(chosen, focus_param)
399+
383400
process_shape(shape_name, root_param)
384401

385402
return body, deps

tests/unit/test_utils.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,29 @@ def test_inline_sh_nodes(shacl_engine):
200200
assert len(shape1_cbd) == 8
201201

202202

203+
def test_get_template_parts_from_shape_with_or():
204+
shape_graph = Graph()
205+
shape_graph.parse(
206+
data=PREAMBLE
207+
+ """
208+
:shape1 a owl:Class, sh:NodeShape ;
209+
sh:or ( :option1 :option2 ) .
210+
:option1 a owl:Class, sh:NodeShape ;
211+
sh:property [
212+
sh:path brick:hasPoint ;
213+
sh:qualifiedValueShape [ sh:class brick:Zone_Air_Temperature_Sensor ] ;
214+
sh:qualifiedMinCount 1 ;
215+
] .
216+
:option2 a owl:Class, sh:NodeShape .
217+
"""
218+
)
219+
body, deps = get_template_parts_from_shape(MODEL["shape1"], shape_graph)
220+
point_targets = list(body.objects(PARAM["name"], BRICK.hasPoint))
221+
assert point_targets
222+
for target in point_targets:
223+
assert (target, A, BRICK.Zone_Air_Temperature_Sensor) in body
224+
225+
203226
def test_inline_sh_and(bm: BuildingMOTIF, shacl_engine):
204227
bm.shacl_engine = shacl_engine
205228
sg = Graph()

0 commit comments

Comments
 (0)