I am looking to see if there is a simple way to deserialize an XML file filled with elements back to a class of properties, specifically on the elements attribute 'name' as the property to attach to. For example, I have an XML file format given as:
<?xml version="1.0" encoding="utf-8"?>
<settings>
<setting name="number_val_one">1</setting>
<setting name="string_val_one">test</setting>
<setting name="number_val_two">42</setting>
<setting name="string_val_two">hello world</setting>
</settings>
I am wondering if there is a simple way to deserialize this back to a class that is similar to this format:
public class SomeObject
{
[XmlElement("number_value_one")]
public Int32 NumberValueOne { get; set; }
[XmlElement("number_value_two")]
public Int32 NumberValueTwo { get; set; }
[XmlElement("string_value_one")]
public String StringValueOne { get; set; }
[XmlElement("string_value_two")]
public String StringValueTwo { get; set; }
}
I understand the format is no the best for serialization and such but I cannot change how the file is formatted for this project. At the moment I am reading each element by hand for its value which is a lot of code and fairly messy. To serialize it back to xml I am using reflection to get around the need to write each element by hand. But I am wondering if there is a simple way to handle this format.
Not all elements are string / int though, some are custom types to be parsed after being read etc.
For one you can use xslt to transform you input string to data recognizable by XmlSerializer.
var transform = new XslCompiledTransform();
transform.Load(XmlReader.Create(new StringReader(transformText)));
var memoryStream = new MemoryStream();
transform.Transform(new XPathDocument(new StringReader(text)),null,memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
var deserializer = new XmlSerializer(typeof(SomeObject)).Deserialize(memoryStream);
where
var transformText = @"
<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">
<xsl:output method=""xml"" encoding=""utf-8"" indent=""no""/>
<xsl:template match=""/"">
<SomeObject>
<xsl:for-each select=""settings/setting"">
<xsl:element name=""{@name}"">
<xsl:value-of select="".""/>
</xsl:element>
</xsl:for-each>
</SomeObject>
</xsl:template>
</xsl:stylesheet>";
and
var text = @"
<settings>
<setting name=""number_val_one"">1</setting>
<setting name=""string_val_one"">test</setting>
<setting name=""number_val_two"">42</setting>
<setting name=""string_val_two"">hello world</setting>
</settings>";
note that setting name attribute value must mach with XmlElementAttribute applied to property.
If you don't understand xslt just search for it there is a lot of examples and references out there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With