diff --git a/dcc-viewer/.idea/.gitignore b/dcc-viewer/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..13566b81b018ad684f3a35fee301741b2734c8f4
--- /dev/null
+++ b/dcc-viewer/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/dcc-viewer/.idea/dcc-viewer.iml b/dcc-viewer/.idea/dcc-viewer.iml
new file mode 100644
index 0000000000000000000000000000000000000000..24643cc37449b4bde54411a80b8ed61258225e34
--- /dev/null
+++ b/dcc-viewer/.idea/dcc-viewer.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.tmp" />
+      <excludeFolder url="file://$MODULE_DIR$/temp" />
+      <excludeFolder url="file://$MODULE_DIR$/tmp" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/dcc-viewer/.idea/inspectionProfiles/Project_Default.xml b/dcc-viewer/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000000000000000000000000000000000000..798a81f55b88f30c729973befe637b412eb0e1dd
--- /dev/null
+++ b/dcc-viewer/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,15 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
+    <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
+      <option name="ignoredPackages">
+        <value>
+          <list size="1">
+            <item index="0" class="java.lang.String" itemvalue="bokeh" />
+          </list>
+        </value>
+      </option>
+    </inspection_tool>
+  </profile>
+</component>
\ No newline at end of file
diff --git a/dcc-viewer/.idea/modules.xml b/dcc-viewer/.idea/modules.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7342473174532c853ba934e45e54b406d31181f1
--- /dev/null
+++ b/dcc-viewer/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/dcc-viewer.iml" filepath="$PROJECT_DIR$/.idea/dcc-viewer.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/dcc-viewer/.idea/vcs.xml b/dcc-viewer/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6c0b8635858dc7ad44b93df54b762707ce49eefc
--- /dev/null
+++ b/dcc-viewer/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/dcc-viewer/package.json b/dcc-viewer/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..019e6c9a0298027cd7ed9ef21b14057326696d68
--- /dev/null
+++ b/dcc-viewer/package.json
@@ -0,0 +1,6 @@
+{
+    "name": "dcc-viewer",
+    "version": "1.0.0",
+    "scripts": { "dev": "vite" },
+    "dependencies": { "xml2js": "^0.4.23" }
+}
\ No newline at end of file
diff --git a/dcc-viewer/public/index.html b/dcc-viewer/public/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..e363a2defb4713e0090763e60902de1e8af3a91a
--- /dev/null
+++ b/dcc-viewer/public/index.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html lang='en'>
+<head>
+    <meta charset='UTF-8'>
+    <title>DCC Viewer</title>
+    <script type='module' src='dist/main.js'></script>
+    <link rel='stylesheet' href='styles.css'>
+</head>
+<body>
+    <input type='file' id='file-input' accept='.xml'>
+    <button id='theme-toggle'>Toggle Theme</button>
+    <select id='language-select'>
+        <option value='en'>English</option>
+        <option value='de'>German</option>
+    </select>
+    <div id='json-container'></div>
+</body>
+</html>
\ No newline at end of file
diff --git a/dcc-viewer/public/styles.css b/dcc-viewer/public/styles.css
new file mode 100644
index 0000000000000000000000000000000000000000..732e263ee63412da84c8ce55819b38924955edca
--- /dev/null
+++ b/dcc-viewer/public/styles.css
@@ -0,0 +1,2 @@
+body { font-family: Arial, sans-serif; }
+.dark-mode { background-color: black; color: white; }
\ No newline at end of file
diff --git a/dcc-viewer/src/components/BaseViewer.ts b/dcc-viewer/src/components/BaseViewer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9837734779dc9fedf19a96a63a1dde407f94bded
--- /dev/null
+++ b/dcc-viewer/src/components/BaseViewer.ts
@@ -0,0 +1,7 @@
+export abstract class BaseViewer {
+    protected sectionData: any;
+    constructor(sectionData: any) {
+        this.sectionData = sectionData;
+    }
+    abstract render(): HTMLElement;
+}
\ No newline at end of file
diff --git a/dcc-viewer/src/components/JSONTreeViewer.ts b/dcc-viewer/src/components/JSONTreeViewer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ef06785f8d63417795abffa62db03ab6687a5b50
--- /dev/null
+++ b/dcc-viewer/src/components/JSONTreeViewer.ts
@@ -0,0 +1,9 @@
+import { BaseViewer } from './BaseViewer';
+
+export class JSONTreeViewer extends BaseViewer {
+    render(): HTMLElement {
+        const container = document.createElement('pre');
+        container.textContent = JSON.stringify(this.sectionData, null, 2);
+        return container;
+    }
+}
\ No newline at end of file
diff --git a/dcc-viewer/src/globalData.ts b/dcc-viewer/src/globalData.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8bc8fad27f3447beb40ca07fbab502e54cf09906
--- /dev/null
+++ b/dcc-viewer/src/globalData.ts
@@ -0,0 +1 @@
+export const globalData: { [key: string]: any } = {};
\ No newline at end of file
diff --git a/dcc-viewer/src/globalOptions.ts b/dcc-viewer/src/globalOptions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..09c0db1e3e8c356dee727322199a42afce569694
--- /dev/null
+++ b/dcc-viewer/src/globalOptions.ts
@@ -0,0 +1 @@
+export const globalOptions = { preferredLanguage: 'en' };
\ No newline at end of file
diff --git a/dcc-viewer/src/idRegistry.ts b/dcc-viewer/src/idRegistry.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e98ebabb82d9a683f703b0be8125426fb3118cfa
--- /dev/null
+++ b/dcc-viewer/src/idRegistry.ts
@@ -0,0 +1 @@
+export const idRegistry: { [id: string]: any } = {};
\ No newline at end of file
diff --git a/dcc-viewer/src/main.ts b/dcc-viewer/src/main.ts
new file mode 100644
index 0000000000000000000000000000000000000000..76059c7323e05f5c438a57ac174d7b1f465a248e
--- /dev/null
+++ b/dcc-viewer/src/main.ts
@@ -0,0 +1,20 @@
+import { convertXMLToJSON } from './xmlToJson';
+import { JSONTreeViewer } from './components/JSONTreeViewer';
+
+const fileInput = document.getElementById('file-input') as HTMLInputElement;
+const container = document.getElementById('json-container') as HTMLElement;
+
+fileInput.addEventListener('change', async (event) => {
+    const file = (event.target as HTMLInputElement).files?.[0];
+    if (!file) return;
+
+    const reader = new FileReader();
+    reader.onload = async () => {
+        const xmlString = reader.result as string;
+        const jsonData = await convertXMLToJSON(xmlString);
+        const viewer = new JSONTreeViewer(jsonData);
+        container.innerHTML = '';
+        container.appendChild(viewer.render());
+    };
+    reader.readAsText(file);
+});
\ No newline at end of file
diff --git a/dcc-viewer/src/ui/languageSelector.ts b/dcc-viewer/src/ui/languageSelector.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0854c83ba9e3297b09e2de4efadc3d75dbac4858
--- /dev/null
+++ b/dcc-viewer/src/ui/languageSelector.ts
@@ -0,0 +1,6 @@
+import { globalOptions } from '../globalOptions';
+
+const languageSelect = document.getElementById('language-select') as HTMLSelectElement;
+languageSelect.addEventListener('change', (event) => {
+    globalOptions.preferredLanguage = (event.target as HTMLSelectElement).value;
+});
\ No newline at end of file
diff --git a/dcc-viewer/src/ui/themeSwitcher.ts b/dcc-viewer/src/ui/themeSwitcher.ts
new file mode 100644
index 0000000000000000000000000000000000000000..931533fbfb34545d350647010ddc6423ac8e7033
--- /dev/null
+++ b/dcc-viewer/src/ui/themeSwitcher.ts
@@ -0,0 +1,4 @@
+const themeToggle = document.getElementById('theme-toggle') as HTMLButtonElement;
+themeToggle.addEventListener('click', () => {
+    document.body.classList.toggle('dark-mode');
+});
\ No newline at end of file
diff --git a/dcc-viewer/src/utils.ts b/dcc-viewer/src/utils.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fb954679dd38700973990e6cdfcdbbceb559f8ee
--- /dev/null
+++ b/dcc-viewer/src/utils.ts
@@ -0,0 +1,4 @@
+export function getLocalizedText(elements: any[]): string {
+    if (!Array.isArray(elements)) return elements;
+    return elements[0]._ || '';
+}
\ No newline at end of file
diff --git a/dcc-viewer/src/viewerRegistry.ts b/dcc-viewer/src/viewerRegistry.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6e6b15a215f39b6009a9a022bf97e5d9f90236a7
--- /dev/null
+++ b/dcc-viewer/src/viewerRegistry.ts
@@ -0,0 +1,5 @@
+import { JSONTreeViewer } from './components/JSONTreeViewer';
+
+export function getViewerForElement(): any {
+    return JSONTreeViewer;
+}
\ No newline at end of file
diff --git a/dcc-viewer/src/xmlToJson.ts b/dcc-viewer/src/xmlToJson.ts
new file mode 100644
index 0000000000000000000000000000000000000000..03506aa0eadb5c00f4a1e0a4f4267a94727ce01d
--- /dev/null
+++ b/dcc-viewer/src/xmlToJson.ts
@@ -0,0 +1,5 @@
+import { parseStringPromise } from 'xml2js';
+
+export async function convertXMLToJSON(xmlString: string): Promise<any> {
+    return parseStringPromise(xmlString, { explicitArray: false, mergeAttrs: true });
+}
\ No newline at end of file
diff --git a/dcc-viewer/tsconfig.json b/dcc-viewer/tsconfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..ff383c8e90473b6687da1ff40ef01ea3588e79dc
--- /dev/null
+++ b/dcc-viewer/tsconfig.json
@@ -0,0 +1 @@
+{ "compilerOptions": { "target": "ES6", "module": "ES6", "outDir": "dist" } }
\ No newline at end of file
diff --git a/project_structure.json b/project_structure.json
index 854fa90fa40dcb75007dbc2ecfde7bc58c4d88fe..ec746423c762356668a8576b74c6d6683bb8cb59 100644
--- a/project_structure.json
+++ b/project_structure.json
@@ -22,6 +22,6 @@
       "styles.css": "body { font-family: Arial, sans-serif; }\n.dark-mode { background-color: black; color: white; }"
     },
     "package.json": "{\n    \"name\": \"dcc-viewer\",\n    \"version\": \"1.0.0\",\n    \"scripts\": { \"dev\": \"vite\" },\n    \"dependencies\": { \"xml2js\": \"^0.4.23\" }\n}",
-    "tsconfig.json": "{ \"compilerOptions\": { \"target\": \"ES6\", \"module\": \"ES6\", \"outDir\": \"dist\" } }",
+    "tsconfig.json": "{ \"compilerOptions\": { \"target\": \"ES6\", \"module\": \"ES6\", \"outDir\": \"dist\" } }"
    }
 }