diff --git a/odml/doc.py b/odml/doc.py
index 279a9b2..4a33cce 100644
--- a/odml/doc.py
+++ b/odml/doc.py
@@ -141,3 +141,21 @@ class BaseDocument(base.Sectionable):
             return None
         term = terminology.load(self.repository)
         return term
+def pprint(self, indent=2, max_depth=1, max_length=80, current_depth=0):
+    """
+    Pretty print method to visualize Document-Section trees.
+
+    :param indent: number of leading spaces for every child Section or Property.
+    :param max_depth: maximum number of hierarchical levels printed from the
+                          starting Section.
+    :param max_length: maximum number of characters printed in one line.
+    :param current_depth: number of hierarchical levels printed from the
+                          starting Section.
+    """
+    doc_str = "[{} [{}] {}, sections: {}, repository: {}]".format(self.author, self.version,
+                                                                  self.date, len(self._sections), self.repository)
+    print(doc_str)
+
+    for s in self._sections:
+        s.pprint(current_depth=current_depth+1, max_depth=max_depth,
+                 indent=indent, max_length=max_length)
diff --git a/odml/dtypes.py b/odml/dtypes.py
index c6e27c3..69cae55 100644
--- a/odml/dtypes.py
+++ b/odml/dtypes.py
@@ -62,6 +62,8 @@ def default_values(dtype):
 
 _dtype_map = {'str': 'string', 'bool': 'boolean'}
 
+special_dtypes = ["url", "person", "text"]
+
 
 def infer_dtype(value):
     dtype = (type(value)).__name__
diff --git a/odml/property.py b/odml/property.py
index 5da9789..a120ab3 100644
--- a/odml/property.py
+++ b/odml/property.py
@@ -82,7 +82,7 @@ class BaseProperty(base.BaseObject):
 
         self._values = []
         self.values = values
-        if not values and (value or isinstance(value, bool)):
+        if not values and (value or isinstance(value, bool) or isinstance(value, int)):
             self.values = value
 
         self.parent = parent
@@ -588,8 +588,10 @@ class BaseProperty(base.BaseObject):
 
         new_value = self._convert_value_input(obj)
         if len(new_value) > 0 and strict and dtypes.infer_dtype(new_value[0]) != self.dtype:
-            raise ValueError("odml.Property.extend: "
-                             "passed value data type does not match dtype!")
+
+            if not (dtypes.infer_dtype(new_value[0]) == "string" and self.dtype in dtypes.special_dtypes):
+                raise ValueError("odml.Property.extend: passed value data type found (\"%s\") "
+                                 "does not match expected dtype \"%s\"!" % (dtypes.infer_dtype(new_value[0]), self._dtype))
 
         if not self._validate_values(new_value):
             raise ValueError("odml.Property.extend: passed value(s) cannot be converted "
@@ -618,8 +620,10 @@ class BaseProperty(base.BaseObject):
             raise ValueError("odml.property.append: Use extend to add a list of values!")
 
         if len(new_value) > 0 and strict and dtypes.infer_dtype(new_value[0]) != self.dtype:
-            raise ValueError("odml.Property.append: "
-                             "passed value data type does not match dtype!")
+
+            if not (dtypes.infer_dtype(new_value[0]) == "string" and self.dtype in dtypes.special_dtypes):
+                raise ValueError("odml.Property.append: passed value data type found (\"%s\") "
+                                 "does not match expected dtype \"%s\"!" % (dtypes.infer_dtype(new_value[0]), self._dtype))
 
         if not self._validate_values(new_value):
             raise ValueError("odml.Property.append: passed value(s) cannot be converted "
diff --git a/odml/tools/version_converter.py b/odml/tools/version_converter.py
index 3d842e8..c7b22ab 100644
--- a/odml/tools/version_converter.py
+++ b/odml/tools/version_converter.py
@@ -9,6 +9,8 @@ from .. import format
 from ..info import FORMAT_VERSION
 from ..terminology import Terminologies, REPOSITORY_BASE
 
+import uuid
+
 try:
     unicode = unicode
 except NameError:
@@ -194,6 +196,8 @@ class VersionConverter(object):
             if e.tag == "repository":
                 self._handle_repository(e)
 
+        tree = self._check_add_ids(tree)
+
         return tree
 
     def _handle_include(self, element):
@@ -410,6 +414,41 @@ class VersionConverter(object):
             elem_map[named_path] += 1
             name.text += "-" + str(elem_map[named_path])
 
+    def _check_add_ids(self, tree):
+        """
+        Checks, whether elements (properties) possess an UUID
+        and adds one in case of absence.
+        :param tree: ElementTree of the doc
+        :return: ElementTree
+        """
+        root = tree.getroot()
+        self._add_id(root)
+        for sec in root.iter("section"):
+            self._add_id(sec)
+            for prop in sec.iter("property"):
+                self._add_id(prop)
+
+        return tree
+
+    @staticmethod
+    def _add_id(element):
+        """
+        Checks, whether an element possesses an ID. If yes, make sure it has
+        the right format. Otherwise a new UUID is created.
+        :param element: lxml element.
+        """
+        oid = element.find("id")
+        new_id = ET.Element("id")
+        new_id.text = str(uuid.uuid4())
+        if oid is not None:
+            try:
+                if oid.text is not None:
+                    new_id.text = str(uuid.UUID(oid.text))
+            except ValueError as e:
+                print(e)
+            element.remove(oid)
+        element.append(new_id)
+
     def _log(self, msg):
         """
         Adds the passed message to the conversion_log attribute and

Add 'Document.pprint' method
Section and Property already feature a pprint method, it would be nice to have one for Document as well.
diff --git a/test/test_property.py b/test/test_property.py
index 80a67d6..80f6c1c 100644
--- a/test/test_property.py
+++ b/test/test_property.py
@@ -103,6 +103,18 @@ class TestProperty(unittest.TestCase):
         with self.assertRaises(ValueError):
             _ = Property(name="Public-Key", value='(5689; 1254; 687)', dtype='2-tuple')
 
+        p3 = Property('myprop', value=0, dtype=DType.int)
+        self.assertEqual(p3.value, [0])
+        self.assertEqual(p3.values, [0])
+
+        p4 = Property('myprop', value=0, dtype=DType.boolean)
+        self.assertEqual(p4.value, [False])
+        self.assertEqual(p4.values, [False])
+
+        p5 = Property('myprop', value=0)
+        self.assertEqual(p5.value, [0])
+        self.assertEqual(p5.values, [0])
+
     def test_value_append(self):
         # Test append w/o Property value or dtype
         prop = Property(name="append")
@@ -183,6 +195,27 @@ class TestProperty(unittest.TestCase):
         self.assertEqual(len(p5), 2)
         self.assertRaises(ValueError, p5.append, "[a, b, c]")
 
+        p6 = Property(name="prop", value=["A Abraham", "B Barnes", "C Clark"], dtype=DType.person)
+        p6.append("D Dickins")
+        self.assertEqual(len(p6), 4)
+        self.assertRaises(ValueError, p6.append, 1)
+        self.assertRaises(ValueError, p6.append, 1.3)
+        self.assertRaises(ValueError, p6.append, True)
+
+        p7 = Property(name="prop", value=["https://en.wikipedia.org/wiki/Earth"], dtype=DType.url)
+        p7.append("https://en.wikipedia.org/wiki/Mars")
+        self.assertEqual(len(p7), 2)
+        self.assertRaises(ValueError, p7.append, 1)
+        self.assertRaises(ValueError, p7.append, 1.3)
+        self.assertRaises(ValueError, p7.append, True)
+
+        p8 = Property(name="prop", value=["Earth is No. 3."], dtype=DType.text)
+        p8.append("Mars is No. 4.")
+        self.assertEqual(len(p8), 2)
+        self.assertRaises(ValueError, p8.append, 1)
+        self.assertRaises(ValueError, p8.append, 1.3)
+        self.assertRaises(ValueError, p8.append, True)
+
     def test_value_extend(self):
         prop = Property(name="extend")
 
@@ -260,6 +293,27 @@ class TestProperty(unittest.TestCase):
         with self.assertRaises(ValueError):
             prop.extend([6, "some text"])
 
+        p1 = Property(name="prop", value=["A Abraham", "B Barnes", "C Clark"], dtype=DType.person)
+        p1.extend("D Dickins")
+        self.assertEqual(len(p1), 4)
+        self.assertRaises(ValueError, p1.extend, 1)
+        self.assertRaises(ValueError, p1.extend, 1.3)
+        self.assertRaises(ValueError, p1.extend, True)
+
+        p2 = Property(name="prop", value=["https://en.wikipedia.org/wiki/Earth"], dtype=DType.url)
+        p2.extend("https://en.wikipedia.org/wiki/Mars")
+        self.assertEqual(len(p2), 2)
+        self.assertRaises(ValueError, p2.append, 1)
+        self.assertRaises(ValueError, p2.append, 1.3)
+        self.assertRaises(ValueError, p2.append, True)
+
+        p3 = Property(name="prop", value=["Earth is No. 3."], dtype=DType.text)
+        p3.extend("Mars is No. 4.")
+        self.assertEqual(len(p3), 2)
+        self.assertRaises(ValueError, p3.append, 1)
+        self.assertRaises(ValueError, p3.append, 1.3)
+        self.assertRaises(ValueError, p3.append, True)
+
     def test_get_set_value(self):
         values = [1, 2, 3, 4, 5]
         p = Property("property", value=values)
diff --git a/test/test_version_converter.py b/test/test_version_converter.py
index 29c28ab..8b166e4 100644
--- a/test/test_version_converter.py
+++ b/test/test_version_converter.py
@@ -272,11 +272,13 @@ class TestVersionConverter(unittest.TestCase):
         conv_doc = vc._convert(vc._parse_xml())
         root = conv_doc.getroot()
 
+        root_id = root.findall("id")
+        self.assertEqual(len(root_id), 1)
         sec = root.findall("section")
         self.assertEqual(len(sec), 2)
 
         # Test valid section tags.
-        self.assertEqual(len(sec[0]), 10)
+        self.assertEqual(len(sec[0]), 11)
         self.assertEqual(sec[0].find("name").text, "Section name")
         self.assertEqual(sec[0].find("type").text, "Section type")
         self.assertEqual(sec[0].find("definition").text, "Section definition")
@@ -286,10 +288,11 @@ class TestVersionConverter(unittest.TestCase):
         self.assertEqual(sec[0].find("include").text, "Section include")
         self.assertEqual(len(sec[0].findall("property")), 2)
         self.assertEqual(len(sec[0].findall("section")), 1)
+        self.assertEqual(len(sec[0].findall("id")), 1)
 
         # Test valid subsection tags.
         subsec = sec[0].find("section")
-        self.assertEqual(len(subsec), 8)
+        self.assertEqual(len(subsec), 9)
         self.assertEqual(subsec.find("name").text, "SubSection name")
         self.assertEqual(subsec.find("type").text, "SubSection type")
         self.assertEqual(subsec.find("definition").text, "SubSection definition")
@@ -298,10 +301,12 @@ class TestVersionConverter(unittest.TestCase):
         self.assertEqual(subsec.find("repository").text, local_url)
         self.assertEqual(subsec.find("include").text, "SubSection include")
         self.assertEqual(len(subsec.findall("property")), 1)
+        self.assertEqual(len(subsec.findall("id")), 1)
 
         # Test absence of non-Section tags
-        self.assertEqual(len(sec[1]), 1)
+        self.assertEqual(len(sec[1]), 2)
         self.assertEqual(len(sec[1].findall("name")), 1)
+        self.assertEqual(len(sec[1].findall("id")), 1)
 
         # Test presence of v1.0 repository tag and warning log entry
         doc = """
@@ -379,19 +384,21 @@ class TestVersionConverter(unittest.TestCase):
         self.assertEqual(sec[0].find("name").text, "Valid Property tags test")
         self.assertEqual(len(sec[0].findall("property")), 1)
         prop = sec[0].find("property")
-        self.assertEqual(len(prop), 5)
+        self.assertEqual(len(prop), 6)
         self.assertEqual(prop.find("name").text, "Property name")
         self.assertEqual(prop.find("type").text, "Property type")
         self.assertEqual(prop.find("definition").text, "Property definition")
         self.assertEqual(prop.find("dependency").text, "Property dependency")
         self.assertEqual(prop.find("dependencyvalue").text, "Property dependency value")
+        self.assertEqual(len(prop.findall("id")), 1)
 
         # Test non-import of Property w/o name
         self.assertEqual(len(sec[1].findall("property")), 1)
         # Test absence of non-Property tags
         prop = sec[1].find("property")
-        self.assertEqual(len(prop), 1)
+        self.assertEqual(len(prop), 2)
         self.assertEqual(len(prop.findall("name")), 1)
+        self.assertEqual(len(prop.findall("id")), 1)
 
     def test_convert_odml_file_value(self):
         """Test proper conversion of the odml.Value entity from
@@ -511,6 +518,22 @@ class TestVersionConverter(unittest.TestCase):
                       <value> 3 <type>int</type></value>
                       <name>testIntListWhiteSpace</name>
                     </property>
+                    
+                     <property>
+                      <name>Single value with UUID</name>
+                      <value>1</value>
+                      <id>aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa</id>
+                    </property>
+                    
+                     <property>
+                      <name>Single value with none-UUID ID</name>
+                      <id>1</id>
+                    </property>
+                    
+                    <property>
+                      <name>Single value with empty ID</name>
+                      <id></id>
+                    </property>
 
                   </section>
                 </odML>
@@ -520,27 +543,33 @@ class TestVersionConverter(unittest.TestCase):
         vc = self.VC(file)
         conv_doc = vc._convert(vc._parse_xml())
         root = conv_doc.getroot()
+        root_id = root.findall("id")
+        self.assertEqual(len(root_id), 1)
         sec = root.find("section")
-        self.assertEqual(len(sec), 14)
+        self.assertEqual(len(sec), 18)
+        self.assertEqual(len(sec.findall("id")), 1)
 
         # Test single value export
         prop = sec.findall("property")[0]
-        self.assertEqual(len(prop), 2)
+        self.assertEqual(len(prop), 3)
         self.assertEqual(prop.find("value").text, "1")
+        self.assertEqual(len(prop.findall("id")), 1)
 
         # Test multiple value export
         prop = sec.findall("property")[1]
-        self.assertEqual(len(prop), 2)
+        self.assertEqual(len(prop), 3)
         self.assertEqual(prop.find("value").text, "[1,2,3]")
+        self.assertEqual(len(prop.findall("id")), 1)
 
         # Test empty value export
         prop = sec.findall("property")[2]
-        self.assertEqual(len(prop), 1)
+        self.assertEqual(len(prop), 2)
         self.assertEqual(prop.find("name").text, "Empty value export")
+        self.assertEqual(len(prop.findall("id")), 1)
 
         # Test valid Value tags
         prop = sec.findall("property")[3]
-        self.assertEqual(len(prop), 7)
+        self.assertEqual(len(prop), 8)
         self.assertEqual(prop.find("value").text, "0.1")
         self.assertEqual(prop.find("type").text, "float")
         self.assertEqual(prop.find("uncertainty").text, "0.05")
@@ -548,58 +577,88 @@ class TestVersionConverter(unittest.TestCase):
         self.assertEqual(prop.find("value_origin").text, "raw.txt")
         self.assertEqual(prop.find("reference").text, "Value reference")
         self.assertEqual(len(prop.findall("filename")), 0)
+        self.assertEqual(len(prop.findall("id")), 1)
 
         # Test valid multiple Value tag export
         prop = sec.findall("property")[4]
-        self.assertEqual(len(prop), 7)
+        self.assertEqual(len(prop), 8)
         self.assertEqual(prop.find("value").text, "[0.1,0.2,3]")
         self.assertEqual(prop.find("type").text, "float")
         self.assertEqual(prop.find("uncertainty").text, "0.05")
         self.assertEqual(prop.find("unit").text, "mV")
         self.assertEqual(prop.find("value_origin").text, "raw.txt")
         self.assertEqual(prop.find("reference").text, "Value reference")
+        self.assertEqual(len(prop.findall("id")), 1)
 
         # Test non-export of invalid Value tags
         prop = sec.findall("property")[5]
-        self.assertEqual(len(prop), 1)
+        self.assertEqual(len(prop), 2)
         self.assertEqual(len(prop.findall("name")), 1)
+        self.assertEqual(len(prop.findall("id")), 1)
 
         # Test dtype 'binary' replacement
         prop = sec.findall("property")[6]
         self.assertEqual(prop.find("name").text, "Unsupported binary value type replace")
         self.assertEqual(prop.find("type").text, "text")
+        self.assertEqual(len(prop.findall("id")), 1)
         prop = sec.findall("property")[7]
         self.assertEqual(prop.find("name").text, "Unsupported binary value dtype replace")
         self.assertEqual(prop.find("type").text, "text")
+        self.assertEqual(len(prop.findall("id")), 1)
 
         # Test single string value with commata
         prop = sec.findall("property")[8]
         self.assertEqual(prop.find("name").text, "testSingleString")
         self.assertEqual(prop.find("value").text,
                          "Single, string, value, with, many, commata.")
+        self.assertEqual(len(prop.findall("id")), 1)
 
         # Test string list import
         prop = sec.findall("property")[9]
         self.assertEqual(prop.find("name").text, "testStringList")
         self.assertEqual(prop.find("value").text, "[A,B,C]")
+        self.assertEqual(len(prop.findall("id")), 1)
 
         # Test single string values wrapping whitespace removal
         prop = sec.findall("property")[10]
         self.assertEqual(prop.find("name").text, "testStringWhiteSpace")
         self.assertEqual(prop.find("value").text,
                          "Single string value with wrapping whitespace")
+        self.assertEqual(len(prop.findall("id")), 1)
 
         # Test multiple string values with wrapping whitespace removal
         prop = sec.findall("property")[11]
         self.assertEqual(prop.find("name").text, "testStringListWhiteSpace")
         self.assertEqual(prop.find("value").text,
                          "[Multiple Strings,with wrapping,Whitespace]")
+        self.assertEqual(len(prop.findall("id")), 1)
 
         # Test multiple int values with wrapping whitespaces
         prop = sec.findall("property")[12]
         self.assertEqual(prop.find("name").text, "testIntListWhiteSpace")
         self.assertEqual(prop.find("type").text, "int")
         self.assertEqual(prop.find("value").text, "[1,2,3]")
+        self.assertEqual(len(prop.findall("id")), 1)
+
+        # Test single value export
+        prop = sec.findall("property")[13]
+        self.assertEqual(len(prop), 3)
+        self.assertEqual(prop.find("value").text, "1")
+        self.assertEqual(len(prop.findall("id")), 1)
+        self.assertEqual(prop.find("id").text, "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa")
+
+        # Test single value export
+        prop = sec.findall("property")[14]
+        self.assertEqual(len(prop), 2)
+        self.assertEqual(len(prop.findall("id")), 1)
+        self.assertNotEqual(prop.find("id").text, "1")
+
+        # Test single value export
+        prop = sec.findall("property")[15]
+        self.assertEqual(len(prop), 2)
+        self.assertEqual(len(prop.findall("id")), 1)
+        self.assertNotEqual(prop.find("id").text, "1")
+
 
     def test_parse_dict_document(self):
         # Test appending tags; not appending empty sections

pip install -e .
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y gcc libxml2-dev libxslt1-dev
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
docopt==0.6.2
exceptiongroup==1.2.2
iniconfig==2.1.0
isodate==0.7.2
lxml==5.3.1
-e git+https://github.com/G-Node/python-odml.git@ed8c0feee642fa2353b62b28491ba0f91fb745e0#egg=odML
packaging==24.2
pathlib==1.0.1
pluggy==1.5.0
pyparsing==3.2.3
pytest==8.3.5
PyYAML==4.2b4
rdflib==7.1.4
tomli==2.2.1

name: python-odml
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - docopt==0.6.2
      - exceptiongroup==1.2.2
      - iniconfig==2.1.0
      - isodate==0.7.2
      - lxml==5.3.1
      - packaging==24.2
      - pathlib==1.0.1
      - pluggy==1.5.0
      - pyparsing==3.2.3
      - pytest==8.3.5
      - pyyaml==4.2b4
      - rdflib==7.1.4
      - tomli==2.2.1
prefix: /opt/conda/envs/python-odml

test/test_property.py::TestProperty::test_value test/test_property.py::TestProperty::test_value_append test/test_property.py::TestProperty::test_value_extend test/test_version_converter.py::TestVersionConverter::test_convert_odml_file_property test/test_version_converter.py::TestVersionConverter::test_convert_odml_file_section test/test_version_converter.py::TestVersionConverter::test_convert_odml_file_value
test/test_property.py::TestProperty::test_bool_conversion test/test_property.py::TestProperty::test_clone test/test_property.py::TestProperty::test_comparison test/test_property.py::TestProperty::test_dtype test/test_property.py::TestProperty::test_get_merged_equivalent test/test_property.py::TestProperty::test_get_path test/test_property.py::TestProperty::test_get_set_value test/test_property.py::TestProperty::test_id test/test_property.py::TestProperty::test_merge test/test_property.py::TestProperty::test_merge_check test/test_property.py::TestProperty::test_name test/test_property.py::TestProperty::test_new_id test/test_property.py::TestProperty::test_parent test/test_property.py::TestProperty::test_simple_attributes test/test_property.py::TestProperty::test_str_to_int_convert test/test_version_converter.py::TestVersionConverter::test_convert_json_file test/test_version_converter.py::TestVersionConverter::test_convert_odml_file test/test_version_converter.py::TestVersionConverter::test_convert_odml_file_document test/test_version_converter.py::TestVersionConverter::test_convert_xml_file test/test_version_converter.py::TestVersionConverter::test_convert_yaml_file test/test_version_converter.py::TestVersionConverter::test_handle_include test/test_version_converter.py::TestVersionConverter::test_handle_repository test/test_version_converter.py::TestVersionConverter::test_parse_dict_document test/test_version_converter.py::TestVersionConverter::test_parse_dict_properties test/test_version_converter.py::TestVersionConverter::test_parse_dict_sections test/test_version_converter.py::TestVersionConverter::test_parse_dict_values test/test_version_converter.py::TestVersionConverter::test_replace_same_name_entites test/test_version_converter.py::TestVersionConverter::test_write_to_file
odml/dtypes.py odml/doc.py odml/property.py odml/tools/version_converter.py
odml/dtypes.py odml/doc.py odml/property.py odml/tools/version_converter.py