###### tags: `data` `ontology` `HN` SHACL === excellente présentatino de T. Francart sur le sujet: https://rbdd.cnrs.fr/local/cache-zotspip/23D7N9G8/Francart%20SHApe%20Constraints%20Language.pdf shacl définit des contraintes sur les triplet. Concrètement il définit des _sh:PropertyShape_ (les contraintes) sur des _sh:NodeShape_ (les classes) ## Node shapes d'abord on définit des "nodeshapes". Ce sont des shapes qui contiennent les objets controlés. __Valeurs__: `rdf:type`: sh:NodeShape forcément! `sh:targetClass`: ensemble des objets controlés par cette shape `sh:nodeKind`: sh:IRI signifie que l'on souhaite que les instances des classes de cette shape soit des IRI, pas des noeuds anonymes. `sh:property`: ce sont les contraintes (_propertyshape_) voir plus bas attaché à la shape. `sh:ignoredPropertie` : ce sont les propriétés owl qui ne seront pas vérifié en mode "closed shapes". On y met toujours au moins `rdf:type`mais aussi toutes les propriétés d'annotation (`rdfs:label`, `skos:prefLabel`, `skos:note`, etc.) ```sparql myPrfx:shaclNode1 rdf:type sh:NodeShape , sh:targetClass crm:E67_Birth ; sh:property crm:E67_Birth-P96_by_mother , crm:E67_Birth-P98_brought_into_life , crm:E67_Birth-P97_from_father . ``` shortcut: Si seule une classe est controlée on peut garder son IRI et ne pas renseigner de _sh:targetClass_. C'est ce que fait sparna. L'exemple précéent peut être ré-écrit comme suit: ```sparql crm:E67_Birth rdf:type sh:NodeShape , rdfs:Class ; sh:property crm:E67_Birth-P96_by_mother , crm:E67_Birth-P98_brought_into_life , crm:E67_Birth-P97_from_father . ``` ## Property shapes Ensuite on définit les contraintes, ce sont les "propertyshape" Chaque propertyshape est une nouvelle contrainte. Dans l'exemple précédent, pour la classe`E67_BIrth` la _sh:property_ `<crm:E67_Birth-P96_by_mother>` est une contrainte que l'on va définir ici. __Valeurs__: `rdf:type`: sh:PropertyShape forcément! `sh:path` : la propriété owl concernée `sh:class`: classe attendue comme valeur de la propriété owl (si une seule) `sh:or`: classes attendues comme valeurs de la propriété (si plusieurs) ex: ```sparql crm:E67_Birth-P96_by_mother rdf:type sh:PropertyShape ; sh:path crm:P96_by_mother . sh:class crm:E21_Person ; ``` ## Conclusion pour domain range on définit des contraintes pour chaque shape. Si je reprends mon exemple et que je met tout dans la même shape (je décloisonne) ça donne ```sparql crm:E67_Birth rdf:type sh:NodeShape , rdfs:Class ; sh:property [ sh:path crm:P96_by_mother ; sh:class crm:E21_Person ; ] . ``` ## autre écriture Il est possible de cible avec d'autres outils que `targetClass`par exemple avec `sh:targeSubjectOf`ou `sh:targObjectOf ` pour récupérer les sujets/objets des triplet associée à une propriété owl. On peut alors écrire par exemple: ```sparql ex:p98shape rdf:type sh:NodeShape; sh:targeSubjectOf crm:P98_brought_into_life; sh:property [ sh:class crm:E67_Birth ] . ``` ## Pour d'autres contraintes il est possible de définir d'autres contraintes sur les shapes. ### cardinalité Par exemple, on veut qu'il y ait 0 ou 1 mère seulement par Birth. on peut écrire: ```sparql crm:E67_Birth-P96_by_mother rdf:type sh:PropertyShape ; sh:path crm:P96_by_mother . sh:class crm:E21_Person ; sh:maxCount 1 ``` ### type #### IRI or not On veut que le type de la mère soit un IRI (pas une chaine de char) ```sparql crm:E67_Birth-P96_by_mother rdf:type sh:PropertyShape ; sh:path crm:P96_by_mother . sh:class crm:E21_Person ; sh:maxCount 1 sh:nodeKind sh:IRI ``` #### non IRI: autres types Par exemple on veut que la mère soit une chaine de char (et pas un IRI) et corresponde à un pattern ```sparql crm:E67_Birth-P96_by_mother rdf:type sh:PropertyShape ; sh:path crm:P96_by_mother . sh:class crm:E21_Person ; sh:maxCount 1 sh:nodeKind sh:BlankNodeOrLiteral sh:datatype xsd:string sh:pattern "^[mM]adame .+$" ; ```