diff --git a/config.json b/config.json
index d9a3d259d319af9dcccd6571203d9f5031406d1a..75bf22b49683a91f1f0b4423b39a0c23208f15de 100644
--- a/config.json
+++ b/config.json
@@ -4,8 +4,6 @@
     "port": 5005
   },
   "xsd":{
-    "filename":"dcc.xsd",
-    "externalBaseURL":"https://ptb.de/dcc/",
-    "localPath":"./xsd-local/"
+    "releases":"https://www.ptb.de/dcc/releases.json"
   }
 }
diff --git a/server.py b/server.py
index 05471f86e2aacaa67bbd4dda8a941d99e261e862..3ecb26c1682189e9c2ba3018eaabc4e47038aa6b 100644
--- a/server.py
+++ b/server.py
@@ -3,11 +3,13 @@ from flask_cors import CORS
 import utils as utils
 from trans import Trans
 from datetime import datetime
-import subprocess
+import subprocess, json
 from pprint import pprint
 
 config = utils.get_config_dict()
-
+releases_dict = utils.get_releases_dict(config['xsd']['releases'])
+versions = utils.get_versions(releases_dict) 
+        
 app = Flask(__name__)
 CORS(app)
 trans = Trans()
@@ -46,30 +48,33 @@ def update():
 @app.route('/validate', methods=['POST'])
 def validate():
     app.logger.debug('hit validate')
-    xv = request.args.get('v')
+    version = request.args.get('v')
     xml_str = request.data
     xml_tree = utils.parse(xml_str)
-    if xml_tree:
+    try:
+        utils.parse(xml_str)
         app.logger.debug('=== xml_tree OK ===')
-        xsd_str = utils.get_xsd(config, xsd_version=xv, xml_str=xml_str)
+        xsd_str = utils.get_xsd(releases_dict, xsd_version=version, xml_str=xml_str)
         if  xsd_str:
+            app.logger.debug('=== xsd OK ===')
             ret = utils.validate(xml_str=xml_str, xsd_str=xsd_str)
         else:
+            app.logger.debug('=== xsd invalid ===')
             ret = utils.return_error(error='xsd content not readable')
-    else: 
-        app.logger.debug('=== xml_tree invalid ===') 
-        ret = utils.return_error(error='invalid xml data')
+    except:
+        app.logger.debug('=== xml_tree invalid ===')
+        ret = utils.return_error(error='invalid xml data')   
 
     return  utils.xml_response(ret)
     
 @app.route('/validation.html', methods=['GET'])
 def validation():
     app.logger.debug('hit validation.html')
-    # pprint(vars(request)) 
     l = str(request.accept_languages).split(',')[0][0:2]
     if l != 'de':
         l = 'en'
-    x = "['2.4.0','2.3.0','2.2.0','2.1.1','2.1.0']"
+    # x = '["2.4.0","2.3.0","2.2.0","2.1.1","2.1.0"]'
+    x = '[' + ','.join(versions) + ']'# javascript array definition as string 
     return trans.show_html(version=utils.get_version(), language=l, 
       xsd_versions=x)
 
@@ -90,3 +95,5 @@ def logo_folder(fn):
 
 if __name__ == '__main__':
     app.run(host=config['server']['host'], port=config['server']['port'])
+
+
diff --git a/templates/html/validation.html b/templates/html/validation.html
index 6fd88ecffba2ba09f60b38a98949d3dd97998c6e..65a3a20613be1726559573928317b38e6b0a9a3d 100644
--- a/templates/html/validation.html
+++ b/templates/html/validation.html
@@ -39,7 +39,6 @@
         <strong style="margin-left:5em;" >{{XSD_VERSION}}:</strong>
         <select id="xsd_version" size="1">
           <option>{{INTERNAL}}</option>
-          <option>{{LATEST}}</option>
         </select>
 
     </div>
@@ -68,7 +67,6 @@
       function getXSDversion() {
         const idx = $xsd_v.prop('selectedIndex');
         if (idx == 0) return false;
-        if (idx == 1) return 'latest';
         return $xsd_v.val();
       }
       function _showError(s) {
diff --git a/utils.py b/utils.py
index cffec5b31d87deae12388e9a92f3f9b4ddd90aa9..1c815c81e9862b3a19d9dfccf5dec287af989200 100644
--- a/utils.py
+++ b/utils.py
@@ -21,6 +21,29 @@ def get_config_dict():
 
     return config
 
+# get content of 'releases.json' via http request
+def get_releases_dict(url):
+    try:
+        filename = urlparse(url).path.split('/')[-1]
+        r = requests.get(url, allow_redirects=True)
+        if r.url.endswith(filename): # no bad redirection
+            try:
+                return json.loads(r.text)
+            except:
+                return False         
+        else:
+            return False
+    except:
+        return False  
+
+# a reverse list of version strings        
+def get_versions(d):
+    v = []
+    for i in d['releases']:
+        v.append('"' + i['version'] + '"') 
+    v = list(reversed(v))
+    return v
+
 def get_version():
     try:
         with open('./VERSION', 'r') as f:
@@ -29,38 +52,21 @@ def get_version():
     except:
         return False
 
-def get_xsd(cfg, xsd_version=None, xml_str = None):
-    filename =  cfg['xsd']['filename']
-    baseURL = cfg['xsd']['externalBaseURL']
-    xsd_str = ''
+def get_xsd(d, xsd_version=None, xml_str = None):
     url = ''
-    if xsd_version:
-        if xsd_version == 'latest':
-            url = baseURL + filename
-        else:
-            url = baseURL + 'v' + xsd_version + '/' + filename
-    else:
+    version = xsd_version
+    if not version: # We use the internal version information in the XML data
         root = parse(xml_str)
-        item = root.attrib.get('schemaVersion')
-        if item:
-            url = baseURL + 'v' + item + '/' + filename
-        else:
-            for key in root.attrib:
-                if key.endswith('schemaLocation'):
-                    x = root.attrib.get(key).split()
-                    for u in x:
-                        if u.endswith(filename):
-                            url = u
-                            break       
-    if uri_validator(url):
-        try:
-            r = requests.get(url, allow_redirects=True)
-            if r.url.endswith(filename): # no bad redirection
-                return r.text
-            else:
-                return False
-        except:
-            return False
+        version = root.attrib.get('schemaVersion')
+    for i in d['releases']:
+        if i['version'] == version:
+            url = i['url']
+            break
+    try:
+        r = requests.get(url, allow_redirects=True)
+        return r.text
+    except:
+        return False
 
 def parse(xml_str):
     try: