Skip to content

Commit

Permalink
Implement generation of enriched namespaces file, reorganize project …
Browse files Browse the repository at this point in the history
…to depend on the new file

The new XML contains user namespaces (defined in namespaces.xml) and internal
namespaces (such as core-shape). Both model2owl internals and get_namespaces.sh
relies on that file and not on namespaces.xml. Moreover, model2owl internals now
depends on a new template which generates namespaces declarations based on
enriched file which is passed to the XSLT transformation engine as command line
argument. For now, the path of the new XML file is kept in the Makefile, but
this can be further improved in the future (if we come up with application
internal XSL config or other solution).

Scope of changes:
* new XSL file for generation of the enriched namespaces XML file
* unit test for the above XSL file
* project codebase:
  * new function generating namespaces declarations and references to
    `$namespacePrefixes` replaced with `$internalNamespacePrefixes`
* Makefile changes:
  * new recipe
  * existing 3 recipes generating *.rdf artefacts now include generation of the
    new XML file
  * required adjustments
* Adjustments in the get_namespaces.sh script
  • Loading branch information
gkostkowski committed Sep 20, 2024
1 parent f4a9247 commit a8596c6
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 36 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -325,3 +325,4 @@ lib64
pyvenv.cfg
/build/
/node_modules/
.temp
34 changes: 25 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

# Model2owl directory
MODEL2OWL_FOLDER?=.
ABSOLUTE_MODEL2OWL_FOLDER?=$(shell realpath "${MODEL2OWL_FOLDER}")
# rdflib version
RDF_LIB_VERSION?=6.2.0
#Saxon path
Expand Down Expand Up @@ -33,8 +34,10 @@ TURTLE_FILELIST=$(shell ls ${ONTOLOGY_FOLDER_PATH}/*.ttl)
# Widoco variables
WIDOCO_RDF_INPUT_FILE_PATH?=test/reasoning-investigation/model-2020-12-16/ePO_restrictions.rdf
WIDOCO_OUTPUT_FOLDER_PATH?=output/widoco
NAMESPACES_XML_FILE_PATH?=${MODEL2OWL_FOLDER}/test/ePO-default-config/namespaces.xml
NAMESPACES_AS_RDFPIPE_ARGS=$(shell ${MODEL2OWL_FOLDER}/scripts/get_namespaces.sh ${NAMESPACES_XML_FILE_PATH})
NAMESPACES_USER_XML_FILE_PATH?=${MODEL2OWL_FOLDER}/test/ePO-default-config/namespaces.xml
INTERM_FOLDER_PATH?=${ABSOLUTE_MODEL2OWL_FOLDER}/.temp
ENRICHED_NAMESPACES_XML_PATH:=${INTERM_FOLDER_PATH}/enriched-namespaces.xml
NAMESPACES_AS_RDFPIPE_ARGS=$(shell ${MODEL2OWL_FOLDER}/scripts/get_namespaces.sh ${ENRICHED_NAMESPACES_XML_PATH})
RDF_XML_MIME_TYPE:='application/rdf+xml'
TURTLE_MIME_TYPE:='turtle'

Expand Down Expand Up @@ -114,8 +117,10 @@ generate-convention-SVRL-report:
#Example how to run transformation commands :
# make owl-core XMI_INPUT_FILE_PATH=/home/mypc/work/model2owl/eNotice_CM.xml OUTPUT_FOLDER_PATH=./my-folder
owl-core:
@make gen-enriched-ns-file
@java -jar ${SAXON} -s:${XMI_INPUT_FILE_PATH} -xsl:${MODEL2OWL_FOLDER}/src/owl-core.xsl \
-o:${OUTPUT_FOLDER_PATH}/${XMI_INPUT_FILENAME_WITHOUT_EXTENSION}.tmp.rdf
-o:${OUTPUT_FOLDER_PATH}/${XMI_INPUT_FILENAME_WITHOUT_EXTENSION}.tmp.rdf \
enrichedNamespacesPath="${ENRICHED_NAMESPACES_XML_PATH}"
@make convert-between-serialization-formats INPUT_FORMAT=${RDF_XML_MIME_TYPE} \
OUTPUT_FORMAT=${RDF_XML_MIME_TYPE} \
FILE_PATH=${OUTPUT_FOLDER_PATH}/${XMI_INPUT_FILENAME_WITHOUT_EXTENSION}.tmp.rdf \
Expand All @@ -125,8 +130,10 @@ owl-core:
@rm -f ${OUTPUT_FOLDER_PATH}/${XMI_INPUT_FILENAME_WITHOUT_EXTENSION}.tmp.rdf

owl-restrictions:
@make gen-enriched-ns-file
@java -jar ${SAXON} -s:${XMI_INPUT_FILE_PATH} -xsl:${MODEL2OWL_FOLDER}/src/owl-restrictions.xsl \
-o:${OUTPUT_FOLDER_PATH}/${XMI_INPUT_FILENAME_WITHOUT_EXTENSION}_restrictions.tmp.rdf
-o:${OUTPUT_FOLDER_PATH}/${XMI_INPUT_FILENAME_WITHOUT_EXTENSION}_restrictions.tmp.rdf \
enrichedNamespacesPath="${ENRICHED_NAMESPACES_XML_PATH}"
@make convert-between-serialization-formats INPUT_FORMAT=${RDF_XML_MIME_TYPE} \
OUTPUT_FORMAT=${RDF_XML_MIME_TYPE} \
FILE_PATH=${OUTPUT_FOLDER_PATH}/${XMI_INPUT_FILENAME_WITHOUT_EXTENSION}_restrictions.tmp.rdf \
Expand All @@ -136,8 +143,10 @@ owl-restrictions:
@rm -f ${OUTPUT_FOLDER_PATH}/${XMI_INPUT_FILENAME_WITHOUT_EXTENSION}_restrictions.tmp.rdf

shacl:
@make gen-enriched-ns-file
@java -jar ${SAXON} -s:${XMI_INPUT_FILE_PATH} -xsl:${MODEL2OWL_FOLDER}/src/shacl-shapes.xsl \
-o:${OUTPUT_FOLDER_PATH}/${XMI_INPUT_FILENAME_WITHOUT_EXTENSION}_shapes.tmp.rdf
-o:${OUTPUT_FOLDER_PATH}/${XMI_INPUT_FILENAME_WITHOUT_EXTENSION}_shapes.tmp.rdf \
enrichedNamespacesPath="${ENRICHED_NAMESPACES_XML_PATH}"
@make convert-between-serialization-formats INPUT_FORMAT=${RDF_XML_MIME_TYPE} \
OUTPUT_FORMAT=${RDF_XML_MIME_TYPE} \
FILE_PATH=${OUTPUT_FOLDER_PATH}/${XMI_INPUT_FILENAME_WITHOUT_EXTENSION}_shapes.tmp.rdf \
Expand All @@ -146,6 +155,12 @@ shacl:
@ls -lh ${OUTPUT_FOLDER_PATH}/${XMI_INPUT_FILENAME_WITHOUT_EXTENSION}_shapes.rdf
@rm -f ${OUTPUT_FOLDER_PATH}/${XMI_INPUT_FILENAME_WITHOUT_EXTENSION}_shapes.tmp.rdf

# Generate enriched namespaces XML file which contains user namespaces (defined
# in namespaces.xml) and internal namespaces (such as core-shape)
gen-enriched-ns-file:
@mkdir -p ${INTERM_FOLDER_PATH}
@java -jar ${SAXON} -s:${NAMESPACES_USER_XML_FILE_PATH} -xsl:${MODEL2OWL_FOLDER}/src/xml/enriched-namespaces.xsl \
-o:${ENRICHED_NAMESPACES_XML_PATH}

# Combine xmi UML files
# all files for combine should be in test/test-multi-xmi (or in XMI_MERGED_OUTPUT_FOLDER_PATH)
Expand Down Expand Up @@ -220,10 +235,11 @@ convert-rdf-to-rdf:
# OUTPUT_FILE_PATH: Path for the output file
# INPUT_FORMAT: a MIME type of the given input RDF file
# OUTPUT_FORMAT: a MIME type of any of the valid RDF serializations
# USE_NAMESPACES: optional; if non-empty then namespaces (from the namespaces.xml file).
# This can be used if the input (FILE_PATH) doesn't include
# namespaces we want to be applied (e.g. to have compact
# instead of full URIs in the output file).
# USE_NAMESPACES: optional; if non-empty then namespaces (from the
# enriched-namespaces.xml file). This can be used if the input
# (FILE_PATH) doesn't include namespaces we want to be applied
# (e.g. to have compact instead of full URIs in the output
# file).
#
# Supported MIME types: https://rdflib.readthedocs.io/en/7.0.0/plugin_serializers.html
#
Expand Down
10 changes: 6 additions & 4 deletions scripts/get_namespaces.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#!/bin/bash
#
# Gets namespaces from an XML file with the model2owl project namespaces
# (`namespaces.xml` by default) and prepares argument list from them to be
# used with `rdfpipe` tool. Uses Saxon installed in the project main directory.
# Gets namespaces from an XML file with the model2owl project namespaces and
# prepares argument list from them to be used with `rdfpipe` tool. Uses Saxon
# installed in the project main directory.
#
# USAGE: get_namespaces.sh NAMESPACES_XML_FILE_PATH
PROJECT_DIR=$(dirname $(dirname $(realpath ${BASH_SOURCE[0]})))
SAXON=${PROJECT_DIR}/saxon/saxon.jar

if [ -z "$1" ]; then
echo "ERROR: path to *.xml file with namespaces not given."
Expand All @@ -17,7 +19,7 @@ namespaces_file_name=$(basename $namespaces_file_path)

cd ${namespaces_file_dir}
namespaces=$(
java -cp ../../saxon/saxon.jar net.sf.saxon.Query -s:${namespaces_file_name} \
java -cp $SAXON net.sf.saxon.Query -s:${namespaces_file_name} \
-qs:'for $x in /*:prefixes/*:prefix return concat(string($x/@name), "=", string($x/@value))' \
\!method=text
)
Expand Down
8 changes: 4 additions & 4 deletions src/common/checkers.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -512,15 +512,15 @@
</xsl:function>

<xd:doc>
<xd:desc> This function will check if a given list of namespaces are defined in
namespaces.xml file. If not all the namespaces were defined it will return a list with
those namespaces</xd:desc>
<xd:desc> This function will check if a given list of namespaces are
defined in enriched-namespaces.xml file. If not all the namespaces were
defined it will return a list with those namespaces</xd:desc>
<xd:param name="listOfNamespaces"/>
</xd:doc>
<xsl:function name="f:isAllNamespacesDefined">
<xsl:param name="listOfNamespaces"/>
<xsl:variable name="definedNamespaces"
select="($namespacePrefixes/*:prefixes/*:prefix/@name)"/>
select="($internalNamespacePrefixes/*:prefixes/*:prefix/@name)"/>
<xsl:variable name="listOfNotDefinedNamespaces"
select="functx:value-except($listOfNamespaces, $definedNamespaces)"/>
<xsl:sequence
Expand Down
18 changes: 17 additions & 1 deletion src/common/utils.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@
<xsl:import href="fetchers.xsl"/>
<xsl:import href="functx-1.0.1-doc.xsl"/>

<xsl:param name="enrichedNamespacesPath"/>
<xsl:variable name="internalNamespacePrefixes" select="
if (boolean($enrichedNamespacesPath)) then
fn:doc($enrichedNamespacesPath)
else fn:error(xs:QName('missing-parameter'), 'enrichedNamespacesPath is not given.')
"/>

<xd:doc>
<xd:desc> Lookup a data-type in the xsd and rdf accepted data-type document (usually an
external file with xsd and rdf data-types definitions) and return false or the data-type
Expand Down Expand Up @@ -61,7 +68,7 @@
<xsl:function name="f:getNamespaceURI" as="xs:string">
<xsl:param name="prefix"/>

<xsl:variable name="fetch" select="f:getNamespaceValues($prefix, $namespacePrefixes)"/>
<xsl:variable name="fetch" select="f:getNamespaceValues($prefix, $internalNamespacePrefixes)"/>
<xsl:sequence
select="
if (boolean($fetch)) then
Expand Down Expand Up @@ -492,4 +499,13 @@
/>
</xsl:function>

<xd:doc>
<xd:desc>This template declares set of namespaces to be defined in top element of an output file</xd:desc>
</xd:doc>
<xsl:template name="namespacesDeclaration">
<xsl:for-each select="$internalNamespacePrefixes/*:prefixes/*:prefix">
<xsl:namespace name="{./@name}" select="./@value"/>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>
6 changes: 2 additions & 4 deletions src/owl-core.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@
</xd:doc>
<xsl:template match="/">
<rdf:RDF>
<xsl:for-each select="$namespacePrefixes/*:prefixes/*:prefix">
<xsl:namespace name="{./@name}" select="./@value"/>
</xsl:for-each>
<xsl:call-template name="namespacesDeclaration"/>
<xsl:call-template name="ontology-header"/>
<xsl:apply-templates/>
<xsl:call-template name="generalisationsWithDistinctTargetsInCoreLayer"/>
Expand All @@ -63,7 +61,7 @@
<xsl:template name="ontology-header">

<owl:Ontology rdf:about="{$coreArtefactURI}">
<xsl:for-each select="$namespacePrefixes/*:prefixes/*:prefix/@importURI">
<xsl:for-each select="$internalNamespacePrefixes/*:prefixes/*:prefix/@importURI">
<owl:imports rdf:resource="{.}"/>
</xsl:for-each>

Expand Down
8 changes: 2 additions & 6 deletions src/owl-restrictions.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,7 @@
</xd:doc>
<xsl:template match="/">
<rdf:RDF>
<xsl:for-each select="$namespacePrefixes/*:prefixes/*:prefix">
<xsl:namespace name="{./@name}" select="./@value"/>
</xsl:for-each>
<xsl:namespace name="{fn:concat($moduleReference, '-res')}" select="fn:concat($base-restriction-uri,$defaultDelimiter)"/>

<xsl:call-template name="namespacesDeclaration"/>
<xsl:call-template name="ontology-header"/>
<xsl:apply-templates/>
<xsl:call-template name="generalisationsWithDistinctTargetsInReasoningLayer"/>
Expand All @@ -58,7 +54,7 @@
</xd:doc>
<xsl:template name="ontology-header">
<owl:Ontology rdf:about="{$restrictionsArtefactURI}">
<xsl:for-each select="$namespacePrefixes/*:prefixes/*:prefix/@importURI">
<xsl:for-each select="$internalNamespacePrefixes/*:prefixes/*:prefix/@importURI">
<owl:imports rdf:resource="{.}"/>
</xsl:for-each>
<owl:imports rdf:resource="{$coreArtefactURI}"/>
Expand Down
10 changes: 2 additions & 8 deletions src/shacl-shapes.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,7 @@
</xd:doc>
<xsl:template match="/">
<rdf:RDF>
<xsl:for-each select="$namespacePrefixes/*:prefixes/*:prefix">
<xsl:namespace name="{./@name}" select="./@value"/>
</xsl:for-each>
<xsl:namespace name="{fn:concat($moduleReference, '-res')}" select="fn:concat($base-restriction-uri,$defaultDelimiter)"/>
<xsl:namespace name="{fn:concat($moduleReference, '-shape')}" select="fn:concat($base-shape-uri,$defaultDelimiter)"/>


<xsl:call-template name="namespacesDeclaration"/>
<xsl:call-template name="ontology-header"/>
<xsl:apply-templates/>
</rdf:RDF>
Expand All @@ -62,7 +56,7 @@
<xsl:template name="ontology-header">
<owl:Ontology rdf:about="{$shapeArtefactURI}">

<xsl:for-each select="$namespacePrefixes/*:prefixes/*:prefix/@importURI">
<xsl:for-each select="$internalNamespacePrefixes/*:prefixes/*:prefix/@importURI">
<owl:imports rdf:resource="{.}"/>
</xsl:for-each>
<owl:imports rdf:resource="{$coreArtefactURI}"/>
Expand Down
36 changes: 36 additions & 0 deletions src/xml/enriched-namespaces.xsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns="http://publications.europa.eu/ns/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="xd xsl fn"
version="3.0">

<xsl:import href="../../config-proxy.xsl"/>
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />

<xd:doc>
<xd:desc>
A template for generating enriched namespaces XML file that
contains internal model2owl namespaces which are constructed
based on the model2owl configuration.
</xd:desc>
</xd:doc>
<xsl:template match="/">
<prefixes>
<xsl:for-each select="/*:prefixes/*:prefix">
<prefix name="{./@name}" value="{./@value}">
<xsl:if test="boolean(./@importURI)">
<xsl:attribute name="importURI">
<xsl:value-of select="./@importURI" />
</xsl:attribute>
</xsl:if>
</prefix>
</xsl:for-each>
<prefix name="{fn:concat($moduleReference, '-res')}"
value="{fn:concat($base-restriction-uri,$defaultDelimiter)}"/>
<prefix name="{fn:concat($moduleReference, '-shape')}"
value="{fn:concat($base-shape-uri,$defaultDelimiter)}"/>
</prefixes>
</xsl:template>
</xsl:stylesheet>
18 changes: 18 additions & 0 deletions test/unitTests/test-xml/test-enriched-namespaces.xspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?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:xs="http://www.w3.org/2001/XMLSchema"
stylesheet="../../../src/xml/enriched-namespaces.xsl">

<x:scenario label="Scenario testing completeness of the generated enriched namespaces">
<x:context href="../../ePO-default-config/namespaces.xml" select="/"/>
<x:variable name="userNamespacesCnt" as="xs:integer"
href="../../ePO-default-config/namespaces.xml"
select="fn:count(//*:prefixes/*:prefix)"/>
<x:expect label="there is 1 top-level prefix element" test="count(*:prefixes) = 1"/>
<x:expect label="there are user-defined namespaces"
test="fn:count(*:prefixes/*:prefix) >= $userNamespacesCnt"/>
<x:expect label="there is an internal namespace"
test="*:prefixes/*:prefix[@name = 'core-shape'] = 'http://data.europa.eu/a4g/data-shape#'"/>
</x:scenario>
</x:description>

0 comments on commit a8596c6

Please sign in to comment.