diff --git a/src/soil/component.py b/src/soil/component.py
index 4c507d6c40a95235c788832a99186f6dfc7e969f..869f3896f90eac723e34e38c4fc56f178ca20069 100644
--- a/src/soil/component.py
+++ b/src/soil/component.py
@@ -19,6 +19,7 @@ from .error import ChildNotFoundException
 from .function import Function
 from .measurement import Measurement
 from .parameter import Parameter
+from .semantics import Namespaces
 from ..utils import root_logger
 from ..utils.constants import HTTP_GET
 from ..utils.error import SerialisationException, DeviceException, UserException
@@ -395,23 +396,23 @@ class Component(Element):
         return result
 
     def resolve_semantic_path(self, path: List[str]):
-        if len(path) == 0:
-            raise ChildNotFoundException('Could not resolve the semantic path.')
+        try:
+            super().resolve_semantic_path(path)
+        except ChildNotFoundException:
+            triples = list(self._metadata.triples((None, Namespaces.rdf.type, None)))
+            triples = list(filter(lambda x: x[2] == Namespaces.ssn.System, triples))
+            assert len(triples) > 0
+
+            if path[0] == triples[0][0].split('/')[-1] and len(path) == 1:
+                return self, 'metadata'
 
-        # first try to resolve whether it is a path to a profile
-        if path[0] == f'{self._profilename}Shape':
-            if len(path) == 1:
-                return self, 'profile'
-        else:
             for child in self.children:
                 try:
                     return child.resolve_semantic_path(path)
                 except ChildNotFoundException:
                     continue
 
-        # TODO resolve data or metadata terms
-
-        raise ChildNotFoundException('Could not resolve the semantic path.')
+            raise ChildNotFoundException('Could not resolve the semantic path.')
 
 
 
diff --git a/src/soil/element.py b/src/soil/element.py
index c248859527f5b54a39d1f458bf0f27d725fab607..3fb465723d1f8edcf29df793c0cbe6eb80870d84 100644
--- a/src/soil/element.py
+++ b/src/soil/element.py
@@ -6,6 +6,7 @@ from typing import Any, Dict, List
 import rdflib
 
 from .error import ChildNotFoundException
+from .semantics import Namespaces
 from ..utils.constants import BASE_UUID_PATTERN, HTTP_GET
 from ..utils.error import SerialisationException
 
@@ -118,7 +119,6 @@ class Element(ABC):
 
         if path[0] == f'{self._profilename}Shape' and len(path) == 1:
             return self, 'profile'
-        else:
-            raise ChildNotFoundException('Could not resolve the semantic path.')
 
-    # TODO resolve data or metadata terms
+        raise ChildNotFoundException('Could not resolve the semantic path.')
+
diff --git a/src/soil/function.py b/src/soil/function.py
index 04131ff79633093e1d05d7f1e177e0f1b610e581..c9aad47d8710442369b6b3191473cc6f786a58f6 100644
--- a/src/soil/function.py
+++ b/src/soil/function.py
@@ -1,16 +1,15 @@
-import functools
 import inspect
 from typing import Any, Dict, List, Union, Callable
 
 import rdflib
 
 from .element import Element
-from .error import InvokationException, NotImplementedException
-from ..utils import root_logger
-from ..utils.error import SerialisationException, DeviceException
+from .error import InvokationException, NotImplementedException, ChildNotFoundException
 from .figure import Figure
 from .parameter import Parameter
+from ..utils import root_logger
 from ..utils.constants import HTTP_GET, HTTP_OPTIONS
+from ..utils.error import SerialisationException, DeviceException
 
 logger = root_logger.get(__name__)
 
@@ -54,7 +53,8 @@ class Function(Element):
             for o in everything:
                 if o.uuid == item[0]:
                     return o[item[1:]]
-            raise Exception("{}: Given uuid {} is not the id of a child of the current component!".format(self.uuid, item))
+            raise Exception(
+                "{}: Given uuid {} is not the id of a child of the current component!".format(self.uuid, item))
         return super().__getitem__(item, method)
 
     def __setitem__(self, key: str, value: Any):
@@ -121,7 +121,8 @@ class Function(Element):
                 var = [x for x in self._returns if x['uuid'] == uuid]
                 if len(var) != 1:
                     raise InvokationException(self._uuid, self._name,
-                                              "Internal Server Error. UUID {} of returned parameter does not match!".format(uuid))
+                                              "Internal Server Error. UUID {} of returned parameter does not match!".format(
+                                                  uuid))
                 else:
                     var = var[0]
                     Figure.check_all(var.datatype, var.dimension, var.range, value)
@@ -135,11 +136,14 @@ class Function(Element):
         dictionary = super().serialize(keys, legacy_mode)
         if 'arguments' in keys:
             dictionary['arguments'] = list(
-                map(lambda x: x.serialize(['name', 'uuid', 'description', 'datatype', 'value', 'dimension', 'range', 'ontology'], legacy_mode, HTTP_OPTIONS),
+                map(lambda x: x.serialize(
+                    ['name', 'uuid', 'description', 'datatype', 'value', 'dimension', 'range', 'ontology'], legacy_mode,
+                    HTTP_OPTIONS),
                     self._arguments))
         if 'returns' in keys:
             dictionary['returns'] = list(
-                map(lambda x: x.serialize(['name', 'uuid', 'description', 'datatype', 'dimension', 'ontology'], legacy_mode, HTTP_OPTIONS), self._returns))
+                map(lambda x: x.serialize(['name', 'uuid', 'description', 'datatype', 'dimension', 'ontology'],
+                                          legacy_mode, HTTP_OPTIONS), self._returns))
         return dictionary
 
     @staticmethod
@@ -149,15 +153,19 @@ class Function(Element):
         uuid = dictionary['uuid']
         if uuid[:3] != 'FUN':
             raise SerialisationException(
-                'The Function can not be deserialized. The UUID must start with FUN, but actually starts with {}!'.format(uuid[:3]))
+                'The Function can not be deserialized. The UUID must start with FUN, but actually starts with {}!'.format(
+                    uuid[:3]))
         if 'name' not in dictionary:
             raise SerialisationException('{}: The function can not be deserialized. Name is missing!'.format(uuid))
         if 'description' not in dictionary:
-            raise SerialisationException('{}: The function can not be deserialized. Description is missing!'.format(uuid))
+            raise SerialisationException(
+                '{}: The function can not be deserialized. Description is missing!'.format(uuid))
         if 'arguments' not in dictionary:
-            raise SerialisationException('{}: The function can not be deserialized. List of arguments is missing!'.format(uuid))
+            raise SerialisationException(
+                '{}: The function can not be deserialized. List of arguments is missing!'.format(uuid))
         if 'returns' not in dictionary:
-            raise SerialisationException('{}: The function can not be deserialized. List of returns is missing!'.format(uuid))
+            raise SerialisationException(
+                '{}: The function can not be deserialized. List of returns is missing!'.format(uuid))
 
         try:
             arguments = []
@@ -174,7 +182,8 @@ class Function(Element):
         try:
             ontology = dictionary['ontology'] if 'ontology' in dictionary else None
             profile = dictionary['profile'] if 'profile' in dictionary else None
-            return Function(dictionary['uuid'], dictionary['name'], dictionary['description'], arguments, returns, implementation, ontology, profile)
+            return Function(dictionary['uuid'], dictionary['name'], dictionary['description'], arguments, returns,
+                            implementation, ontology, profile)
         except Exception as e:
             raise SerialisationException('{}: The function can not be deserialized. {}'.format(uuid, e))
 
@@ -185,3 +194,7 @@ class Function(Element):
     def serialize_semantics(self, kind: str) -> rdflib.Graph:
         # This method does nothing intentionally, as we do not have any semantic definition for function
         return None
+
+    def resolve_semantic_path(self, path: List[str]) -> ('Element', str):
+        # This method does nothing intentionally, as we do not have any semantic definition for function
+        raise ChildNotFoundException('Could not resolve the semantic path.')
diff --git a/src/soil/measurement.py b/src/soil/measurement.py
index 3dee1c151c1e805d002eb57366e8dd96037e1372..a6aabb757c8d656e99a3a43c545210aeb9f9ea9d 100644
--- a/src/soil/measurement.py
+++ b/src/soil/measurement.py
@@ -1,17 +1,17 @@
 import datetime
 import warnings
-from typing import Dict, Callable, List, Any
+from typing import Dict, Callable, List
 
 import rdflib
 from deprecated import deprecated
-from rdflib import BNode
 
 from .datatype import Datatype
+from .error import ChildNotFoundException
 from .figure import Figure
+from .semantics import Semantics, Namespaces
 from ..utils import root_logger
 from ..utils.constants import HTTP_GET
 from ..utils.error import SerialisationException, DeviceException
-from .semantics import Semantics, Namespaces
 
 logger = root_logger.get(__name__)
 
@@ -193,8 +193,10 @@ class Measurement(Figure):
             # create observation node
             data_graph.add((observation_subject, Namespaces.rdf.type, rdflib.URIRef(Namespaces.sosa.Observation)))
             data_graph.add((observation_subject, Namespaces.schema.name, rdflib.Literal(f'{self._name} Observation')))
-            data_graph.add((observation_subject, Namespaces.sosa.observedProperty, Semantics.namespace[self._semantic_name]))
-            data_graph.add((observation_subject, Namespaces.sosa.hasResult, Semantics.namespace[f'{self._semantic_name}Measurement']))
+            data_graph.add(
+                (observation_subject, Namespaces.sosa.observedProperty, Semantics.namespace[self._semantic_name]))
+            data_graph.add((observation_subject, Namespaces.sosa.hasResult,
+                            Semantics.namespace[f'{self._semantic_name}Measurement']))
             data_graph.add((observation_subject, Namespaces.sosa.madeBySensor, sensor_triples[0][2]))
 
             # create result node
@@ -210,7 +212,8 @@ class Measurement(Figure):
             rdf_value = Figure.serialize_value(data_graph, self.__getitem__('value', 0))
 
             data_graph.add((measurement_subject, Namespaces.qudt.value, rdf_value))
-            data_graph.add((measurement_subject, Namespaces.schema.dateCreated, rdflib.Literal(datetime.datetime.now().astimezone())))
+            data_graph.add((measurement_subject, Namespaces.schema.dateCreated,
+                            rdflib.Literal(datetime.datetime.now().astimezone())))
 
             # TODO add uncertainty
 
@@ -218,3 +221,16 @@ class Measurement(Figure):
         else:
             raise DeviceException('The provided kind of semantic information cannot be returned.')
         return result
+
+    def resolve_semantic_path(self, path: List[str]) -> ('Element', str):
+        try:
+            super().resolve_semantic_path(path)
+        except ChildNotFoundException:
+            triples = list(self._metadata.triples((None, Namespaces.rdf.type, None)))
+            triples = list(filter(lambda x: x[2] == Namespaces.sosa.ObservableProperty, triples))
+            assert len(triples) > 0
+
+            if path[0] == triples[0][0].split('/')[-1] and len(path) == 1:
+                return self, 'metadata'
+
+            raise ChildNotFoundException('Could not resolve the semantic path.')
diff --git a/src/soil/parameter.py b/src/soil/parameter.py
index d4f86fef7f9f9659a3e9e75b52c1555a63178d63..a10e7ab079249d1c2b6c09ea83810680766952c0 100644
--- a/src/soil/parameter.py
+++ b/src/soil/parameter.py
@@ -6,7 +6,7 @@ from typing import Dict, Callable, Any, List
 import rdflib
 
 from .datatype import Datatype
-from .error import ReadOnlyException
+from .error import ReadOnlyException, ChildNotFoundException
 from .figure import Figure
 from .semantics import Semantics, Namespaces
 from ..utils import root_logger
@@ -153,3 +153,16 @@ class Parameter(Figure):
         else:
             raise DeviceException('The provided kind of semantic information cannot be returned.')
         return result
+
+    def resolve_semantic_path(self, path: List[str]) -> ('Element', str):
+        try:
+            super().resolve_semantic_path(path)
+        except ChildNotFoundException:
+            triples = list(self._metadata.triples((None, Namespaces.rdf.type, None)))
+            triples = list(filter(lambda x: x[2] == Namespaces.ssn.Property, triples))
+            assert len(triples) > 0
+
+            if path[0] == triples[0][0].split('/')[-1] and len(path) == 1:
+                return self, 'metadata'
+
+            raise ChildNotFoundException('Could not resolve the semantic path.')
\ No newline at end of file