Is there a way to save all metadata from a zip file than add it back later?

I need to save the metadata information of a zip file, unzip it make some changes on the file, compress it again and add back the metadata.
I tried to get all metadata using this method: Exporting metadata properties | Documentation. The problem is that the objects with Metadata or MetadataArray type don’t get exported.
I also tried getting all the properties (like here:Read & Extract Metadata of ZIP Files in C# .NET Applications) and saving them to an xml file, but the same problem persisted.
So the first part of my question is, what can be done about these Metadata types?

To add new properties or update the metadata I need to use the PropertyValue class, but this takes only the base types as constructor arguments. So is there a way to add these Metadata types back?

1 Like

@zsiklodi

Please take a look at this screenshot.jpg (66.7 KB). Do you mean these (highlighted) objects are not showing/exporting any data?
What changes/metadata properties you updated or added in the source file and you are expecting them in Metadata or MetadataArray object? Could you please share the complete steps/code to reproduce this issue?

Please share the constructor arguments that you are expecting.

// Before we do anything we try to save the metadata information
using (Metadata metadata = new Metadata("input.zip"))
{
	// Fetch all metadata properties from the file
	var properties = metadata.FindProperties(p => true);
	using(var writer = new XmlTextWriter("importedmetadata.xml", null))
	{
		writer.Formatting = Formatting.Indented;
		writer.WriteStartDocument();
		writer.WriteStartElement("Metadata");
		foreach (var property in properties)
		{
			switch (property.Value.Type)
			{
				case MetadataPropertyType.Metadata:
					// some way to export these
					break;
				case MetadataPropertyType.String:
				case MetadataPropertyType.TimeSpan:
				case MetadataPropertyType.Boolean:
				case MetadataPropertyType.DateTime:
				case MetadataPropertyType.Double:
				case MetadataPropertyType.Empty:
				case MetadataPropertyType.Guid:
				case MetadataPropertyType.Integer:
				case MetadataPropertyType.Long:
					writer.WriteStartElement("Property");
					writer.WriteAttributeString("Name", property.Name.ToString());
					writer.WriteAttributeString("Type", property.Value.Type.ToString());
					writer.WriteAttributeString("Value", property.Value.ToString());
					writer.WriteEndElement();
					break;

				case MetadataPropertyType.MetadataArray:
					// some way to export these
					break;
				case MetadataPropertyType.PropertyValueArray:
					// some way to export these
					break;
				case MetadataPropertyType.ByteArray:
				case MetadataPropertyType.DoubleArray:
				case MetadataPropertyType.IntegerArray:
				case MetadataPropertyType.LongArray:
				case MetadataPropertyType.StringArray:
					writer.WriteStartElement("Property");
					writer.WriteAttributeString("Name", property.Name.ToString());
					writer.WriteAttributeString("Type", property.Value.Type.ToString());
					IEnumerable enumerable2 = property.Value.RawValue as IEnumerable;
					foreach (var value in enumerable2)
					{
						writer.WriteStartElement("Value");
						writer.WriteAttributeString("Value", value.ToString());
						writer.WriteEndElement();
					}
					writer.WriteEndElement();
					break;
			}
		}
		writer.WriteEndElement();
	}
}

// Work on files in zip
// Zip again
using (Metadata metadata = new Metadata(zipPath))
{
	// Fetch all metadata properties from the file
	var properties = metadata.FindProperties(p => true);

	// Remove properties
	foreach (var property in properties.ToList())
	{
		metadata.RemoveProperties(p => p.Name == property.Name);
	}

	// Process the xml above
	using (var reader = new XmlTextReader("importedmetadata.xml"))
	{
		while (reader.Read())
		{
			if (reader.LocalName == "Property")
			{
				var name = reader.GetAttribute("Name");
				var type = reader.GetAttribute("Type");
				if (reader.IsEmptyElement)
				{
					var value = reader.GetAttribute("Value");
					AddMetadataWithType(metadata, value, type, name);
				}
				else
				{
					reader.Read();
					var list = new List<string>();
					while (reader.NodeType != XmlNodeType.EndElement)
					{
						if (reader.LocalName == "Value")
						{
							var value = reader.GetAttribute("Value");
							list.Add(value);
						}
						reader.Read();
					}

					AddMetadataListWithType(metadata, list, type, name);
				}
			}
		}
	}

	metadata.Save("output.zip");
}

For further understandability: there are certain zip types like Adobe’s .xd, where some specific metadata is added. I want to export this information(without knowing what these properties actually are or mean) so the exported .xd(for example) can be opened with Adobe. The method above I tried might be wrong, my main question is: Is there a way to save all the metadata information as it is, do some work then compress and add them back again as they were?

@zsiklodi

We are investigating this scenario. Your investigation ticket ID is METADATANET-3940. You’ll be notified in case of any update.