Skip to content

Commit

Permalink
Support translation of rdf:PlainLiteral to alternative properties in …
Browse files Browse the repository at this point in the history
…SHACL shapes

This was requested in #219
The extension is configurable and can be disabled (it's enabled by default).

Scope:
* implementation
* new configuration parameter
* tests
  • Loading branch information
gkostkowski committed Nov 19, 2024
1 parent 005499f commit 6cdcdf1
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 10 deletions.
37 changes: 27 additions & 10 deletions src/shacl-shape-lib/elements-shacl-shape.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -263,16 +263,33 @@
f:getUmlDataTypeValues($attributeType, $umlDataTypesMapping)
else
$attributeType"/>
<xsl:variable name="datatypeURI"
select="
if ($attributeType = $controlledListType) then
f:buildURIfromLexicalQName('skos:Concept')
else
f:buildURIfromLexicalQName($datatype)"/>

<rdf:Description rdf:about="{$shapePropertyUri}">
<sh:datatype rdf:resource="{$datatypeURI}"/>
</rdf:Description>
<xsl:choose>
<xsl:when test="$attributeType = 'rdf:PlainLiteral'
and fn:boolean($translatePlainLiteralToStringTypesInSHACL)">
<rdf:Description rdf:about="{$shapePropertyUri}">
<sh:or rdf:parseType="Collection">
<rdf:Description>
<sh:datatype rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
</rdf:Description>
<rdf:Description>
<sh:datatype rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"/>
</rdf:Description>
</sh:or>
</rdf:Description>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="datatypeURI"
select="
if ($attributeType = $controlledListType) then
f:buildURIfromLexicalQName('skos:Concept')
else
f:buildURIfromLexicalQName($datatype)"/>

<rdf:Description rdf:about="{$shapePropertyUri}">
<sh:datatype rdf:resource="{$datatypeURI}"/>
</rdf:Description>
</xsl:otherwise>
</xsl:choose>

</xsl:if>
<xsl:if
Expand Down
6 changes: 6 additions & 0 deletions test/ePO-default-config/config-parameters.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@
'https://www.omg.org/spec/UML/20161101'
)"/>

<!-- If enabled then any occurence of rdf:PlainLiteral datatype will be
replaced in a SHACL shape. A list of the two string datatypes will be used
instead: (xsd:string, rdf:langString).
-->
<xsl:variable name="translatePlainLiteralToStringTypesInSHACL" select="fn:true()"/>

<!-- _______________________________________________________________________ -->
<!-- METADATA SECTION -->
<!-- _______________________________________________________________________ -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<x:description
xmlns:x="http://www.jenitennison.com/xslt/xspec"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:uml="http://www.omg.org/spec/UML/20131001"
xmlns:xmi="http://www.omg.org/spec/XMI/20131001"
xmlns:umldi="http://www.omg.org/spec/UML/20131001/UMLDI"
xmlns:dc="http://www.omg.org/spec/UML/20131001/UMLDC"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:dct="http://purl.org/dc/terms/"
xmlns:skos="http://www.w3.org/2004/02/skos/core#"
xmlns:sh="http://www.w3.org/ns/shacl#"
stylesheet="../../../src/shacl-shape-lib/elements-shacl-shape.xsl">

<!-- default value -->
<x:param name="translatePlainLiteralToStringTypesInSHACL" select="fn:true()"/>

<x:scenario label="Scenario for attribute range shape for a class type with translated rdf:PlainLiteral datatype">
<x:call template="attributeRangeShape">
<x:param name="attribute" href="../../testData/ePO_core.xml" select="/xmi:XMI/xmi:Extension[1]/elements[1]/element[55]/attributes[1]/attribute[2]"/>
<x:param name="className" select="'epo:ProcurementObject'"/>
</x:call>
<x:expect label="there is an rdf:Description" test="boolean(rdf:Description) "/>
<x:expect label="there is no sh:class" test="not(boolean(rdf:Description/sh:class))"/>
<x:expect label="rdf:PlainLiteral is translated into ( xsd:string || rdf:langString )">
<rdf:Description rdf:about="http://data.europa.eu/a4g/data-shape#epo-ProcurementObject-epo-hasAdditionalInformation">
<sh:or rdf:parseType="Collection">
<rdf:Description>
<sh:datatype rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
</rdf:Description>
<rdf:Description>
<sh:datatype rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString"/>
</rdf:Description>
</sh:or>
</rdf:Description>
</x:expect>
</x:scenario>

</x:description>
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<x:description
xmlns:x="http://www.jenitennison.com/xslt/xspec"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:uml="http://www.omg.org/spec/UML/20131001"
xmlns:xmi="http://www.omg.org/spec/XMI/20131001"
xmlns:umldi="http://www.omg.org/spec/UML/20131001/UMLDI"
Expand All @@ -13,6 +14,8 @@
xmlns:sh="http://www.w3.org/ns/shacl#"
stylesheet="../../../src/shacl-shape-lib/elements-shacl-shape.xsl">

<x:param name="translatePlainLiteralToStringTypesInSHACL" select="fn:false()"/>

<x:scenario label="Scenario for testing template with match 'element[@xmi:type = 'uml:Class']">
<x:context href="../../testData/ePO-CM_v.3.0.1.eap.xmi" select="/xmi:XMI/xmi:Extension[1]/elements[1]/element[224]"/>
<x:expect label="there is a sh:NodeShape" test="boolean(sh:NodeShape) "/>
Expand Down Expand Up @@ -69,6 +72,20 @@
<x:expect label="there is a sh:class" test="boolean(rdf:Description/sh:class)"/>
<x:expect label="there is no sh:datatype" test="not(boolean(sh:property/sh:PropertyShape/sh:datatype))"/>
</x:scenario>

<x:scenario label="Scenario for attribute range shape for a class type with rdf:PlainLiteral datatype">
<x:call template="attributeRangeShape">
<x:param name="attribute" href="../../testData/ePO_core.xml" select="/xmi:XMI/xmi:Extension[1]/elements[1]/element[55]/attributes[1]/attribute[2]"/>
<x:param name="className" select="'epo:ProcurementObject'"/>
</x:call>
<x:expect label="there is an rdf:Description" test="boolean(rdf:Description) "/>
<x:expect label="there is no sh:class" test="not(boolean(rdf:Description/sh:class))"/>
<x:expect label="rdf:PlainLiteral remains unchanged">
<rdf:Description rdf:about="http://data.europa.eu/a4g/data-shape#epo-ProcurementObject-epo-hasAdditionalInformation">
<sh:datatype rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#PlainLiteral"/>
</rdf:Description>
</x:expect>
</x:scenario>

<x:scenario label="Scenario for attribute multiplicity values are not any (*)">
<x:call template="attributeMultiplicity">
Expand Down

0 comments on commit 6cdcdf1

Please sign in to comment.