diff --git a/src/main.rs b/src/main.rs
index 2560a78..b9764a1 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -281,8 +281,20 @@ impl eframe::App for Generator<'_> {
             tags: Vec<String>,
             characters: Vec<String>,
             */
-            text_input(ui, &mut self.metadata[0].genre, "Genre", false);
             // TODO tag list (List of bordered labels with plus that opens a new text edit)
+
+            ui.horizontal(|row| {
+                row.label("Tags:");
+                &mut self.metadata[0].tags.retain(|x| x != "");
+                for mut tag in &mut self.metadata[0].tags {
+                    text_input(row, &mut tag, "", false);
+                }
+                if row.button("+").clicked() {
+                    &self.metadata[0].tags.push(" ".to_string());
+                };
+            });
+
+            text_input(ui, &mut self.metadata[0].genre, "Genre", false);
             ui.horizontal(|row| {
                 row.label("Page Count:");
                 if row.button("-").clicked() {
diff --git a/src/metadata/mod.rs b/src/metadata/mod.rs
index 1d0dd42..bd44cac 100644
--- a/src/metadata/mod.rs
+++ b/src/metadata/mod.rs
@@ -1,11 +1,11 @@
 use std::{fs::File, io::{Write, Cursor}};
 use quick_xml::{se::Serializer, events::BytesStart};
 use serde::{Serialize, Deserialize};
+use serde::ser::{SerializeSeq, SerializeStruct};
 
 use serde_xml_rs::{to_string, to_writer};
 
-
-#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
+#[derive(Debug, Deserialize, PartialEq, Clone)]
 pub(crate) struct Metadata<'a> {
     #[serde(rename = "@xmlns:xsi")]
     xsi: &'a str,
@@ -13,70 +13,38 @@ pub(crate) struct Metadata<'a> {
     #[serde(rename = "@xsi:noNamespaceSchemaLocation")]
     namespace: &'a str,
 
-    #[serde(rename(serialize="Title"))]
     pub(crate) title: String,
 
-    #[serde(rename(serialize="Series"))]
     pub(crate) series: String,
 
-    #[serde(rename(serialize="Number"))]
     pub(crate) number: u16,
 
-    #[serde(rename(serialize="Count"))]
     pub(crate) count: i16,
 
-    #[serde(rename(serialize="Volume"))]
     pub(crate) volume: i16,
 
-    #[serde(rename(serialize="Summary"))]
-    #[serde(skip_serializing_if = "Option::is_none")]
     pub(crate) summary: Option<String>,
 
-    #[serde(rename(serialize="Year"))]
     pub(crate) year: i16,
-    #[serde(rename(serialize="Month"))]
     pub(crate) month: i8,
-    #[serde(rename(serialize="Day"))]
     pub(crate) day: i8,
 
-    #[serde(rename(serialize="Writer"))]
-    #[serde(skip_serializing_if = "Option::is_none")]
     pub(crate) writer: Option<String>,
-
-    #[serde(rename(serialize="Letterer"))]
-    #[serde(skip_serializing_if = "Option::is_none")]
     pub(crate) letterer: Option<String>,
-
-    #[serde(rename(serialize="Editor"))]
-    #[serde(skip_serializing_if = "Option::is_none")]
     pub(crate) editor: Option<String>,
-
-    #[serde(rename(serialize="Translator"))]
-    #[serde(skip_serializing_if = "Option::is_none")]
     pub(crate) translator: Option<String>,
-
-    #[serde(rename(serialize="Publisher"))]
-    #[serde(skip_serializing_if = "Option::is_none")]
     pub(crate) publisher: Option<String>,
 
-    #[serde(rename(serialize="Genre"))]
     pub(crate) genre: String,
 
-    #[serde(rename(serialize="Tags"))]
-    #[serde(skip_serializing_if = "Vec::is_empty")]
     pub(crate) tags: Vec<String>,
 
-    #[serde(rename(serialize="PageCount"))]
     pub(crate) page_count: u16,
 
-    #[serde(flatten)]
     pub(crate) language: LanguageISO,
 
-    #[serde(rename(serialize="Characters"))]
-    #[serde(skip_serializing_if = "Vec::is_empty")]
     pub(crate) characters: Vec<String>,
 
-    #[serde(flatten)]
     pub(crate) age_rating: AgeRating
 }
 
@@ -109,6 +77,65 @@ impl Default for Metadata<'_> {
     }
 }
 
+impl Serialize for Metadata<'_> {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::Serializer {
+        let mut out_state = serializer.serialize_struct("Metadata", 22)?;
+        out_state.serialize_field("@xmlns:xsi", &self.xsi)?;
+        out_state.serialize_field("@xsi:noNamespaceSchemaLocation", &self.namespace)?;
+        out_state.serialize_field("Title", &self.title)?;
+        out_state.serialize_field("Series", &self.series)?;
+        out_state.serialize_field("Number", &self.number)?;
+        out_state.serialize_field("Count", &self.count)?;
+        out_state.serialize_field("Volume", &self.volume)?;
+
+        if self.summary.is_some() {
+            out_state.serialize_field("Summary", &self.summary)?;
+        }
+
+        out_state.serialize_field("Year", &self.year)?;
+        out_state.serialize_field("Month", &self.month)?;
+        out_state.serialize_field("Day", &self.day)?;
+
+        if self.writer.is_some() {
+            out_state.serialize_field("Writer", &self.writer)?;
+        }
+
+        if self.letterer.is_some() {
+            out_state.serialize_field("Letterer", &self.letterer)?;
+        }
+
+        if self.editor.is_some() {
+            out_state.serialize_field("Editor", &self.editor)?;
+        }
+
+        if self.translator.is_some() {
+            out_state.serialize_field("Translator", &self.translator)?;
+        }
+
+        if self.publisher.is_some() {
+            out_state.serialize_field("Publisher", &self.publisher)?;
+        }
+
+        out_state.serialize_field("Genre", &self.genre)?;
+
+        if self.tags.len() != 0 {
+            out_state.serialize_field("Tags", &self.tags.join(", "))?;
+        }
+
+        out_state.serialize_field("PageCount", &self.page_count)?;
+
+        out_state.serialize_field("LanguageISO", &self.language.to_string())?;
+
+        if self.characters.len() != 0 {
+            out_state.serialize_field("Characters", &self.characters.join(", "))?;
+        }
+
+        out_state.serialize_field("AgeRating", &self.age_rating.to_string())?;
+
+        out_state.end()
+    }
+}
+
 impl Metadata<'_> {
     pub(crate) fn save_to_xml(&self, path: &str) {
         let mut file = File::create(path).unwrap();