diff --git a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/ArchivePacker.java b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/ArchivePacker.java
index b4a99672547e823cd28b0389fb7501adf15a0786..e18aa9ca3a5c6c71d62abbfba46e80f053603d37 100644
--- a/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/ArchivePacker.java
+++ b/CityDoctorParent/CityDoctorModel/src/main/java/de/hft/stuttgart/citydoctor2/utils/ArchivePacker.java
@@ -80,4 +80,18 @@ public class ArchivePacker {
         }
     }
 
+    public static void packAndDeleteDirectory(String directoryPath) throws IOException {
+        Path path = Path.of(directoryPath);
+        if (!path.toFile().exists()) {
+            throw new IllegalStateException("Directory " + directoryPath + " does not exist");
+        }
+        if (!path.toFile().isDirectory()) {
+            throw new IllegalStateException("Path " + directoryPath + " is not a directory");
+        }
+        String outputPath = path.getParent().resolve(path.getFileName() + ".zip").toString();
+        zipDirectory(outputPath, directoryPath);
+
+        FileUtils.deleteDirectory(path.toFile());
+    }
+
 }
diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/CityDoctorValidation.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/CityDoctorValidation.java
index 9b5e1f134d44e1facfc7a90350093ed8f103c8a8..a85e86912795b2ea674310baad3af2be8aaa5753 100644
--- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/CityDoctorValidation.java
+++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/CityDoctorValidation.java
@@ -21,8 +21,10 @@ package de.hft.stuttgart.citydoctor2;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.nio.file.Path;
 import java.util.List;
 
+import de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import org.citygml4j.core.ade.ADEException;
@@ -72,7 +74,7 @@ public class CityDoctorValidation {
 		String outputFile = getOutputFile(argParser, true);
 		ValidationConfiguration config = getValidationConfig(argParser);
 
-		startValidationProcess(new File(inputFile), xmlOutput, pdfOutput, config, outputFile);
+		startValidationProcess(inputFile, xmlOutput, pdfOutput, config, outputFile);
 	}
 
 	private static String getOutputFile(ArgumentParser argParser, boolean optional) {
@@ -144,13 +146,28 @@ public class CityDoctorValidation {
 			pdfOutputPath = pdfOutput.getAbsolutePath();
 		}
 		try {
-			startValidationProcess(inputFile, xmlOutputPath, pdfOutputPath, config, null);
+			startFileValidation(inputFile, xmlOutputPath, pdfOutputPath, config, null);
 		} catch (CityDoctorWriteException e) {
 			// this does not happen as no output file is specified
 			logger.catching(e);
 		}
 	}
 
+	public static void startValidationProcess(String input, String xmlOutput, String pdfOutput,
+											  ValidationConfiguration config, String outputFile) throws CityDoctorWriteException, CityGmlParseException, IOException, InvalidGmlFileException {
+		File inputFile = new File(input);
+		if (!inputFile.exists()) {
+			logger.error("Input file '{}' does not exist.", input);
+			System.exit(1);
+		}
+		if (inputFile.getName().endsWith(".gml")) {
+			startFileValidation(inputFile, xmlOutput, pdfOutput, config, outputFile);
+		} else if (inputFile.getName().endsWith(".zip")) {
+			startZipValidation(input, xmlOutput, pdfOutput, config, outputFile);
+		}
+	}
+
+
 	/**
 	 * This function will handle the complete validation process
 	 * 
@@ -164,7 +181,7 @@ public class CityDoctorValidation {
 	 * @throws CityGMLBuilderException
 	 * @throws ADEException 
 	 */
-	public static void startValidationProcess(File inputFile, String xmlOutput, String pdfOutput,
+	public static void startFileValidation(File inputFile, String xmlOutput, String pdfOutput,
 			ValidationConfiguration config, String outputFile) throws IOException, CityGmlParseException,
 			InvalidGmlFileException, CityDoctorWriteException {
 
@@ -181,6 +198,29 @@ public class CityDoctorValidation {
 		}
 	}
 
+	public static void startZipValidation(String inputZipFile, String xmlOutput, String pdfOutput,
+										  ValidationConfiguration config, String outputFile) throws CityGmlParseException, IOException {
+		xmlOutput = toDirectoryPath(xmlOutput);
+		pdfOutput = toDirectoryPath(pdfOutput);
+		outputFile = toDirectoryPath(outputFile);
+		if (xmlOutput == null && pdfOutput == null && outputFile == null) {
+			logger.warn("No output locations specified, results of validation will not be saved");
+		}
+		CityGmlZipArchive archive = CityGmlZipArchive.register(inputZipFile);
+		Checker.streamCheck(archive, xmlOutput, pdfOutput, config, outputFile);
+	}
+
+	public static String toDirectoryPath(String input) {
+		if (input == null) {
+			return null;
+		}
+		String parentDirectory = Path.of(input).getParent().toString() + File.separator;
+		String name = Path.of(input).getFileName().toString().replaceFirst("\\..+", "") + File.separator;
+		File f = new File(parentDirectory + name);
+		f.mkdir();
+		return f.getPath() + File.separator;
+	}
+
 	public static String getPdfOutput(ArgumentParser argParser) {
 		if (argParser.containsOption("pdfreport")) {
 			List<String> reportFiles = argParser.getValues("pdfreport");
diff --git a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java
index 58bd27adfdea86f3e1bc55affa11944a5bf206a0..31401b56256c6d3b477fdafee111f1fec9121ad8 100644
--- a/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java
+++ b/CityDoctorParent/CityDoctorValidation/src/main/java/de/hft/stuttgart/citydoctor2/check/Checker.java
@@ -42,6 +42,7 @@ import de.hft.stuttgart.citydoctor2.reporting.XmlStreamReporter;
 import de.hft.stuttgart.citydoctor2.reporting.XmlValidationReporter;
 import de.hft.stuttgart.citydoctor2.reporting.pdf.PdfReporter;
 import de.hft.stuttgart.citydoctor2.reporting.pdf.PdfStreamReporter;
+import de.hft.stuttgart.citydoctor2.utils.ArchivePacker;
 import de.hft.stuttgart.citydoctor2.utils.Localization;
 import de.hft.stuttgart.citydoctor2.zip.CityGmlZipArchive;
 import de.hft.stuttgart.citydoctor2.zip.CityGmlZipEntry;
@@ -740,17 +741,24 @@ public class Checker {
         return hasUnusedDependency;
     }
 
-    public static void streamCheck(CityGmlZipArchive archive, String xmlOutput, String pdfOutput, ValidationConfiguration config,
-                                   String outputFile) throws IOException, CityGmlParseException {
-        streamCheck(archive, xmlOutput, pdfOutput, config, null, outputFile);
+    public static void streamCheck(CityGmlZipArchive archive, String xmlDirectory, String pdfDirectory, ValidationConfiguration config,
+                                   String outputDirectory) throws IOException, CityGmlParseException {
+        streamCheck(archive, xmlDirectory, pdfDirectory, config, null, outputDirectory);
     }
 
-    public static void streamCheck(CityGmlZipArchive archive, String xmlOutput, String pdfOutput, ValidationConfiguration config,
-                                   FeatureCheckedListener l, String outputFile) throws IOException, CityGmlParseException {
+    public static void streamCheck(CityGmlZipArchive archive, String xmlDirectory, String pdfDirectory, ValidationConfiguration config,
+                                   FeatureCheckedListener l, String outputDirectory) throws IOException, CityGmlParseException {
+
 
         for (CityGmlZipEntry entry : archive.getEntries()) {
+            String xmlOutput = xmlDirectory == null ? null : xmlDirectory + entry.getFileName().replaceFirst("\\..+", ".xml");
+            String pdfOutput = pdfDirectory == null ? null : pdfDirectory + entry.getFileName().replaceFirst("\\..+", ".pdf");
+            String outputFile = outputDirectory == null ? null : outputDirectory + entry.getFileName();
             streamCheck(entry, xmlOutput, pdfOutput, config, l, outputFile);
         }
+        if (outputDirectory != null) {
+            ArchivePacker.packAndDeleteDirectory(outputDirectory);
+        }
     }
 
 
diff --git a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java
index 98529774c08bb8083dfb9e53729addc299ddfc47..9fff57921f91778f49ff6acd309afd70f4095895 100644
--- a/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java
+++ b/CityDoctorParent/CityDoctorValidation/src/test/java/de/hft/stuttgart/citydoctor2/check/CheckerTest.java
@@ -35,10 +35,11 @@ import org.junit.rules.TemporaryFolder;
 
 import java.io.File;
 import java.io.IOException;
-import java.nio.file.Files;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 /**
@@ -120,8 +121,8 @@ public class CheckerTest {
 
     @Test
     public void testCliZipChecking() throws IOException, CityDoctorWriteException, CityGmlParseException, InvalidGmlFileException {
-        File f = folder.newFile("out.zip");
-        Files.probeContentType(f.toPath());
+        String output = folder.getRoot().toPath() + File.separator + "test";
+
         try {
             String[] args = new String[6];
             args[0] = "-in";
@@ -129,12 +130,21 @@ public class CheckerTest {
             args[2] = "-config";
             args[3] = "src/test/resources/testConfigWithStreaming.yml";
             args[4] = "-out";
-            args[5] = f.getAbsolutePath();
+            args[5] = output + File.separator;
             CityDoctorValidation.main(args);
+            File f = new File(output + ".zip");
             assertTrue(f.exists());
+            CityGmlZipArchive cgmlArch = CityGmlZipArchive.register(output + ".zip");
+            assertNotNull(cgmlArch);
+            cgmlArch.mountArchive(new ParserConfiguration(8, false));
+            assertEquals(5, cgmlArch.getEntries().size());
+            for (CityGmlZipEntry entry : cgmlArch.getEntries()) {
+                assertNotNull(entry);
+                assertNull(entry.getErrorType());
+            }
 
-        } finally {
-            f.delete();
+        } catch (CityGmlParseException | IOException | InvalidGmlFileException | CityDoctorWriteException e) {
+            throw e;
         }
     }