diff --git a/README.md b/README.md
index 9e610619411f528ecbc92eba5100b60a52f17f07..67c8025e7eccb7a351181eca7b0c09a6016f4b0f 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 [![Build](https://git-ce.rwth-aachen.de/wzl-mq-ms/forschung-lehre/lava/unified-device-interface/python/badges/master/pipeline.svg)](https://git-ce.rwth-aachen.de/wzl-mq-ms/forschung-lehre/lava/unified-device-interface/python/commits/master)
 
 # Python Unified Device Interface
-Current stable version: 9.3.0
+Current stable version: 9.3.1
 
 ## Installation
 1. Install the WZL-UDI package via pip
@@ -58,6 +58,9 @@ Funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation)
 
 ## Recent changes
 
+**9.3.1** - 2024-03-14
+  - fixed semantic name resolution
+
 **9.3.0** - 2024-03-13
   - implemented semantic features for functions
   - refactoring
diff --git a/setup.py b/setup.py
index 64733456bb6e0e707b5baf49626280898671ea75..85c2d036b5128dbdf7e2a9ec760f83208ddc783a 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
     long_description = fh.read()
 
 setup(name='wzl-udi',
-      version='9.3.0',
+      version='9.3.1',
       url='https://git-ce.rwth-aachen.de/wzl-mq-public/soil/python',
       project_urls={
           "Bug Tracker": "https://git-ce.rwth-aachen.de/wzl-mq-public/soil/python/-/issues",
diff --git a/src/http/server.py b/src/http/server.py
index 089f3590508d2d70c767653e5b2d8ba4ea82ff61..0b56d8e689c5077d0cbdec186b6b4d915e119599 100644
--- a/src/http/server.py
+++ b/src/http/server.py
@@ -2,6 +2,7 @@
 import asyncio
 import functools
 import json
+import os
 import traceback
 from typing import Dict, Union
 
@@ -16,16 +17,17 @@ from .error import ServerException
 from ..soil.component import Component
 from ..soil.element import Element
 from ..soil.error import InvokationException, ReadOnlyException, ChildNotFoundException
-from ..soil.variable import Variable
 from ..soil.function import Function
 from ..soil.measurement import Measurement
 from ..soil.parameter import Parameter
-from ..soil.semantics import Semantics
+from ..soil.semantics import Semantics, Namespaces
 from ..soil.stream import StreamScheduler
+from ..soil.variable import Variable
 from ..utils import root_logger
 from ..utils import serialize
 from ..utils.constants import BASE_UUID_PATTERN, HTTP_GET, HTTP_OPTIONS
-from ..utils.error import DeviceException, UserException
+from ..utils.error import DeviceException, UserException, PathResolutionException
+from ..utils.resources import ResourceType
 
 logger = root_logger.get(__name__)
 
@@ -61,7 +63,8 @@ class HTTPServer(object):
     """
 
     def __init__(self, loop: asyncio.AbstractEventLoop, host: str, port: int, model: Component,
-                 dataformat: str = 'json', legacy_mode=False, scheduler: StreamScheduler = None, publisher: MQTTPublisher = None):
+                 dataformat: str = 'json', legacy_mode=False, scheduler: StreamScheduler = None,
+                 publisher: MQTTPublisher = None, profiles_path: str = None):
         """Constructor
 
         Args:
@@ -84,6 +87,7 @@ class HTTPServer(object):
         self._legacy_mode = legacy_mode
         self._scheduler = scheduler
         self._publisher = publisher
+        self._profiles_path = profiles_path
 
         self.app = web.Application(loop=self.loop, middlewares=[cors])
 
@@ -103,6 +107,22 @@ class HTTPServer(object):
         web.run_app(self.app, host=self.host, port=self.port, loop=loop)
         logger.info('HTTP-Server serving on {}:{}'.format(host, port))
 
+    @staticmethod
+    def analyze_request_url(request: Request) -> ResourceType:
+        assert request.url.parts[0] == '/'
+
+        url_parts = request.url.parts
+        if url_parts[-1] == '':
+            url_parts = url_parts[:-1]
+
+        if len(url_parts) == 3 and url_parts[1] == Semantics.prefix:
+            return ResourceType.profile if 'Profile' in url_parts[-1] else ResourceType.metadata
+
+        if request.url.path == '/' or url_parts[-1][:3] in ['COM', 'FUN', 'PAR', 'MEA', 'ARG', 'RET']:
+            return ResourceType.element
+
+        return ResourceType.metadata
+
     @staticmethod
     def parse_uuids(request: Request):
         """Splits the request URL to extract the FQID of the targeted element of the SOIL-Interface.
@@ -173,19 +193,40 @@ class HTTPServer(object):
         logger.info("GET Request from {}".format(request.url))
         logger.debug('Request: {}'.format(request))
         logger.debug('Query Parameters: {}'.format(request.query_string))
-        splitted_request = HTTPServer.parse_uuids(request)
+
+        resource_type = HTTPServer.analyze_request_url(request)
         keys = self._filter_query(request.query)
 
-        # determine whether a semantic answer is expected
-        semantic = None
-        if request.query is not None and 'semantic' in request.query and request.query['semantic'] in ['data', 'metadata', 'profile']:
-            semantic = request.query['semantic']
+        if resource_type == ResourceType.profile:
+            if self._profiles_path is None:
+                raise UserException('Can\'t return requested metadata profile, as no profiles have been created for this sensor service.')
 
-        if len(splitted_request) > 0 and splitted_request[0] == Semantics.prefix:
-            item, semantic = self.root.resolve_semantic_path(splitted_request[1])
+            profilename = request.url.parts[-2] if request.url.parts[-1] == '' else request.url.parts[-1]
+
+            if len(profilename) > 12 and profilename[-12:-8] == 'Range':
+                filename = profilename.replace('RangeProfile', '.shacl.ttl')
+            else:
+                filename = profilename.replace('Profile', '.shacl.ttl')
+
+            profile_path = os.path.join(self._profiles_path, filename)
+            response = rdflib.Graph()
+            response.parse(profile_path)
+            response.add(
+                (rdflib.URIRef(Semantics.namespace[profilename]), Namespaces.dcterms.license, Semantics.profile_license))
+            item, status = None, 200
+
+        elif resource_type == ResourceType.metadata or resource_type == ResourceType.data:
+            item, resource_type = self.root.resolve_semantic_path(request.url.parts[-1])
         else:
+            assert resource_type == ResourceType.element
+            uuids = HTTPServer.parse_uuids(request)
+
+            if request.query is not None and 'semantic' in request.query and request.query[
+                'semantic'] in ResourceType.semantic_resources:
+                resource_type = ResourceType.from_string(request.query['semantic'])
+
             try:
-                item = self.root[splitted_request]
+                item = self.root[uuids]
             except KeyError as e:
                 logger.error(traceback.format_exc())
                 response = {'error': str(e)}
@@ -194,10 +235,10 @@ class HTTPServer(object):
 
         # serializing the element
         try:
-            if semantic:
+            if resource_type.is_semantic() and resource_type != ResourceType.profile:
                 recursive = request.query is not None and 'all' in request.query
-                response = item.serialize_semantics(semantic, recursive)
-            else:
+                response = item.serialize_semantics(resource_type, recursive)
+            elif resource_type == ResourceType.element:
                 response = item.serialize(keys, self._legacy_mode, HTTP_GET)
             status = 200
             logger.info('Response: {}'.format(response))
@@ -206,7 +247,8 @@ class HTTPServer(object):
             response = {'error': str(e)}
             status = 500
             logger.error('Response: {}'.format(response))
-        return self.prepare_response(response, item, status=status, query=request.query, semantic=semantic is not None)
+
+        return self.prepare_response(response, item, status=status, query=request.query, semantic=resource_type.is_semantic())
 
     async def post(self, request):
         logger.info("POST Request from {}".format(request.url))
diff --git a/src/soil/component.py b/src/soil/component.py
index 1df9efc90cc869942c46b0ba811f95c85afea2de..7bafd96d1c3f9596c4c68012efa01a9bd54733fb 100644
--- a/src/soil/component.py
+++ b/src/soil/component.py
@@ -23,6 +23,7 @@ from .semantics import Namespaces, Semantics
 from ..utils import root_logger
 from ..utils.constants import HTTP_GET
 from ..utils.error import SerialisationException, DeviceException, UserException
+from ..utils.resources import ResourceType
 
 logger = root_logger.get(__name__)
 
@@ -385,27 +386,23 @@ class Component(Element):
         for child in self.children:
             child.load_semantics(profiles_path, metadata_path, f"{parent_name}{self.uuid[4:].capitalize()}")
 
-    def serialize_semantics(self, kind: str, recursive=False) -> rdflib.Graph:
-        if self._metadata_profile is None or self._metadata is None:
-            raise SerialisationException('No semantic information have been provided during initialization.')
-
-        if kind == 'profile':
+    def serialize_semantics(self, resource_type: ResourceType, recursive=False) -> rdflib.Graph:
+        if resource_type == ResourceType.profile:
+            if self._metadata is None:
+                raise SerialisationException('No metadata profiles have been provided during initialization.')
             result = self._metadata_profile
-        elif kind == 'metadata':
+
+        elif resource_type == ResourceType.metadata:
+            if self._metadata is None:
+                raise SerialisationException('No semantic information have been provided during initialization.')
             result = self._metadata
+
         else:
-            try:
-                shape_filename = os.path.join(self._profile_path, f'{kind.replace("Profile", "")}.shacl.ttl')
-                result = rdflib.Graph()
-                result.parse(shape_filename)
-                result.add((rdflib.URIRef(Semantics.namespace[kind]), Namespaces.dcterms.license,
-                            Semantics.profile_license))
-            except Exception:
-                raise DeviceException('The provided kind of semantic information cannot be returned.')
+            raise DeviceException('The provided kind of semantic information cannot be returned.')
 
         if recursive:
             for child in self.children:
-                result += child.serialize_semantics(kind, recursive)
+                result += child.serialize_semantics(resource_type, recursive)
 
         return result
 
@@ -424,11 +421,7 @@ class Component(Element):
                     return True
         return False
 
-    def resolve_semantic_path(self, suffix: str) -> (Element, str):
-        # we need to check FIRST if the requested semantic path refers to the profile of a base component of this component
-        if self._is_semantic_path_of_base_profile(self._metadata_profile, suffix):
-            return self, suffix
-
+    def resolve_semantic_path(self, suffix: str) -> (Element, ResourceType):
         try:
             return super().resolve_semantic_path(suffix)
         except ChildNotFoundException:
diff --git a/src/soil/element.py b/src/soil/element.py
index f3e8b95bc6ab7fce63065c258483376b21116c2c..0623b47d6dda4cdb081ed466884b7e4f8ad5b9be 100644
--- a/src/soil/element.py
+++ b/src/soil/element.py
@@ -9,6 +9,7 @@ from .error import ChildNotFoundException
 from .semantics import Namespaces, Semantics
 from ..utils.constants import BASE_UUID_PATTERN, HTTP_GET
 from ..utils.error import SerialisationException
+from ..utils.resources import ResourceType
 
 
 class Element(ABC):
@@ -113,14 +114,12 @@ class Element(ABC):
         self._metadata.add((rdflib.URIRef(self.semantic_name), Namespaces.schema.license, Semantics.metadata_license))
 
     @abstractmethod
-    def serialize_semantics(self, kind: str, recursive: bool = False) -> rdflib.Graph:
+    def serialize_semantics(self, resource_type: ResourceType, recursive: bool = False) -> rdflib.Graph:
         ...
 
-    def resolve_semantic_path(self, suffix: str) -> ('Element', str):
-        if suffix == f'{self._profilename}Profile':
-            return self, 'profile'
-        elif suffix == self.semantic_name.split('/')[-1]:
-            return self, 'metadata'
+    def resolve_semantic_path(self, suffix: str) -> ('Element', ResourceType):
+        if suffix == self.semantic_name.split('/')[-1]:
+            return self, ResourceType.metadata
 
         raise ChildNotFoundException('Could not resolve the semantic path.')
 
diff --git a/src/soil/function.py b/src/soil/function.py
index aaafc792a86d194a1e80503e3acc190ab4d70c9c..fb4b4ec1ebf02c42354d78484f00109eba045f22 100644
--- a/src/soil/function.py
+++ b/src/soil/function.py
@@ -13,6 +13,7 @@ from .parameter import Parameter
 from ..utils import root_logger
 from ..utils.constants import HTTP_GET, HTTP_OPTIONS
 from ..utils.error import SerialisationException, DeviceException
+from ..utils.resources import ResourceType
 
 logger = root_logger.get(__name__)
 
@@ -234,24 +235,27 @@ class Function(Element):
         for child in self._arguments + self._returns:
             child.load_semantics(profiles_path, metadata_path, f"{parent_name}{self.uuid[4:].capitalize()}")
 
-    def serialize_semantics(self, kind: str, recursive=False) -> rdflib.Graph:
-        if self._metadata_profile is None or self._metadata is None:
-            raise SerialisationException('No semantic information have been provided during initialization.')
-
-        if kind == 'profile':
+    def serialize_semantics(self, resource_type: ResourceType, recursive=False) -> rdflib.Graph:
+        if resource_type == ResourceType.profile:
+            if self._metadata is None:
+                raise SerialisationException('No metadata profiles have been provided during initialization.')
             result = self._metadata_profile
-        elif kind == 'metadata':
+
+        elif resource_type == ResourceType.metadata:
+            if self._metadata is None:
+                raise SerialisationException('No semantic information have been provided during initialization.')
+
             result = self._metadata
         else:
             raise DeviceException('The provided kind of semantic information cannot be returned.')
 
         if recursive:
             for child in self._arguments + self._returns:
-                result += child.serialize_semantics(kind, recursive)
+                result += child.serialize_semantics(resource_type, recursive)
 
         return result
 
-    def resolve_semantic_path(self, suffix: str) -> (Element, str):
+    def resolve_semantic_path(self, suffix: str) -> (Element, ResourceType):
         try:
             return super().resolve_semantic_path(suffix)
         except ChildNotFoundException:
diff --git a/src/soil/measurement.py b/src/soil/measurement.py
index f2b7a3f6d9e21518b1f7109a76b3fcc7cb4fc549..a2546e7d32de9c71244935a1eb30524a45d61d47 100644
--- a/src/soil/measurement.py
+++ b/src/soil/measurement.py
@@ -12,6 +12,7 @@ from .semantics import Semantics, Namespaces
 from ..utils import root_logger
 from ..utils.constants import HTTP_GET
 from ..utils.error import SerialisationException, DeviceException
+from ..utils.resources import ResourceType
 
 logger = root_logger.get(__name__)
 
@@ -173,19 +174,21 @@ class Measurement(Variable):
         except Exception as e:
             raise SerialisationException('{}: The measurement can not be deserialized. {}'.format(uuid, e))
 
-    def serialize_semantics(self, kind: str, recursive=False) -> rdflib.Graph:
-        if kind == 'profile':
+    def serialize_semantics(self, resource_type: ResourceType, recursive=False) -> rdflib.Graph:
+        if resource_type == ResourceType.profile:
+            if self._metadata_profile is None:
+                raise SerialisationException('No metadata profiles have been provided during initialization.')
             result = self._metadata_profile
-        elif kind == 'metadata':
+
+        elif resource_type == ResourceType.metadata:
             result = self._metadata
-        elif kind == 'range':
-            range_graph = copy.deepcopy(self._metadata)
-            subjects = range_graph.subjects()
+        elif resource_type == ResourceType.range:
+            result = copy.deepcopy(self._metadata)
+            subjects = result.subjects()
             for subject in subjects:
                 if subject != Semantics.namespace[f'{self._semantic_name}Range']:
-                    range_graph.remove((subject, None, None))
-            return range_graph
-        elif kind == 'data':
+                    result.remove((subject, None, None))
+        elif resource_type == ResourceType.data:
             data_graph = rdflib.Graph()
             data_graph.bind('sosa', Namespaces.sosa)
             data_graph.bind(Semantics.prefix, Semantics.namespace)
diff --git a/src/soil/parameter.py b/src/soil/parameter.py
index f7e862b6972d8c5856e157a34dbc5cc7639f9906..9743aa06a7600df7b23be53d2f599c5121700b31 100644
--- a/src/soil/parameter.py
+++ b/src/soil/parameter.py
@@ -7,11 +7,12 @@ import rdflib
 
 from .datatype import Datatype
 from .error import ReadOnlyException
-from .variable import Variable
 from .semantics import Semantics, Namespaces
+from .variable import Variable
 from ..utils import root_logger
 from ..utils.constants import HTTP_GET
 from ..utils.error import DeviceException, SerialisationException
+from ..utils.resources import ResourceType
 
 logger = root_logger.get(__name__)
 
@@ -136,17 +137,20 @@ class Parameter(Variable):
         else:
             raise ReadOnlyException(self._uuid, self._name)
 
-    def serialize_semantics(self, kind: str, recursive=False) -> rdflib.Graph:
-        if kind == 'profile':
-            result = self._metadata_profile
-        elif kind == 'range':
+    def serialize_semantics(self, resource_type: ResourceType, recursive=False) -> rdflib.Graph:
+        if resource_type == ResourceType.profile:
+            if self._metadata_profile is None:
+                raise SerialisationException('No metadata profiles have been provided during initialization.')
+            return self._metadata_profile
+
+        elif resource_type == ResourceType.range:
             range_graph = copy.deepcopy(self._metadata)
             subjects = range_graph.subjects()
             for subject in subjects:
                 if subject != Semantics.namespace[f'{self._semantic_name}Range']:
                     range_graph.remove((subject, None, None))
             return range_graph
-        elif kind == 'metadata':
+        elif resource_type == ResourceType.metadata:
             result = copy.deepcopy(self._metadata)
 
             triples = list(result.triples((None, Namespaces.qudt['value'], None)))
@@ -159,7 +163,6 @@ class Parameter(Variable):
             return result
         else:
             raise DeviceException('The provided kind of semantic information cannot be returned.')
-        return result
 
     @property
     def semantic_name(self) -> str:
diff --git a/src/soil/variable.py b/src/soil/variable.py
index 3f977369a31668263c3dbb0be27a525c534294ba..c0e59349db581982820e0f12915d1407c5baab6f 100644
--- a/src/soil/variable.py
+++ b/src/soil/variable.py
@@ -11,6 +11,7 @@ import strict_rfc3339 as rfc3339
 
 from .datatype import Datatype
 from .semantics import Namespaces
+from ..utils.resources import ResourceType
 
 nest_asyncio.apply()
 
@@ -321,12 +322,12 @@ class Variable(Element, ABC):
         else:
             raise NotImplementedException(self._uuid, self._name)
 
-    def resolve_semantic_path(self, suffix: str) -> (Element, str):
+    def resolve_semantic_path(self, suffix: str) -> (Element, ResourceType):
         try:
             return super().resolve_semantic_path(suffix)
         except ChildNotFoundException:
             # check if the path fits the range
             if suffix == f'{self.semantic_name.split("/")[-1]}Range':
-                return self, 'range'
+                return self, ResourceType.range
 
             raise ChildNotFoundException('Could not resolve the semantic path.')
diff --git a/src/utils/error.py b/src/utils/error.py
index a6ccecfcec16e9e6e8a943a416506d0234ba2262..b1cbf3044e56ecd6e96e85bb80d9193c07d557d7 100644
--- a/src/utils/error.py
+++ b/src/utils/error.py
@@ -31,4 +31,10 @@ class UserException(BasicException):
 class SerialisationException(DeviceException):
 
     def __init__(self, description):
-        BasicException.__init__(self, description)
\ No newline at end of file
+        BasicException.__init__(self, description)
+
+
+class PathResolutionException(BasicException):
+
+    def __init__(self, description, stack_trace=None, predecessor=None):
+        BasicException.__init__(self, description, stack_trace, predecessor)
diff --git a/src/utils/resources.py b/src/utils/resources.py
new file mode 100644
index 0000000000000000000000000000000000000000..62857be528559991ba0f41cbca6ac06b8063db58
--- /dev/null
+++ b/src/utils/resources.py
@@ -0,0 +1,25 @@
+import enum
+from typing import List
+
+
+class ResourceType(enum.Enum):
+    element = 0
+    profile = 1
+    metadata = 2
+    data = 3
+    range = 4
+
+    def __str__(self) -> str:
+        return self.name
+
+    @classmethod
+    def from_string(cls, value: str) -> 'ResourceType':
+        return cls.__members__[value]
+
+    @classmethod
+    @property
+    def semantic_resources(cls) -> List[str]:
+        return [str(ResourceType.profile), str(ResourceType.metadata), str(ResourceType.data), str(ResourceType.range)]
+
+    def is_semantic(self) -> bool:
+        return self.value in range(1, 5)