I have the following class:
[Serializable] public class SomeModel { [XmlElement("SomeStringElementName")] public string SomeString { get; set; } [XmlElement("SomeInfoElementName")] public int SomeInfo { get; set; } }
Which (when populated with some test data) and Serialized using XmlSerializer.Serialize() results in the following XML:
<SomeModel> <SomeStringElementName>testData</SomeStringElementName> <SomeInfoElementName>5</SomeInfoElementName> </SomeModel>
What I need to have is:
<SomeModel> <SomeStringElementName Value="testData" /> <SomeInfoElementName Value="5" /> </SomeModel>
Is there a way to specify this as attributes without writing my own custom serialization code?
As with the CreatePo method, you must first construct an XmlSerializer, passing the type of the class to be deserialized to the constructor. Also, a FileStream is required to read the XML document. To deserialize the objects, call the Deserialize method with the FileStream as an argument.
By applying the XmlRootAttribute, you can control the XML stream generated by the XmlSerializer. For example, you can change the element name and namespace. The XmlTypeAttribute allows you to control the schema of the generated XML.
An element can have multiple unique attributes. Attribute gives more information about XML elements. To be more precise, they define properties of elements. An XML attribute is always a name-value pair.
XML serialization is the process of converting XML data from its representation in the XQuery and XPath data model, which is the hierarchical format it has in a Db2® database, to the serialized string format that it has in an application.
You will need wrapper classes:
public class SomeIntInfo { [XmlAttribute] public int Value { get; set; } } public class SomeStringInfo { [XmlAttribute] public string Value { get; set; } } public class SomeModel { [XmlElement("SomeStringElementName")] public SomeStringInfo SomeString { get; set; } [XmlElement("SomeInfoElementName")] public SomeIntInfo SomeInfo { get; set; } }
or a more generic approach if you prefer:
public class SomeInfo<T> { [XmlAttribute] public T Value { get; set; } } public class SomeModel { [XmlElement("SomeStringElementName")] public SomeInfo<string> SomeString { get; set; } [XmlElement("SomeInfoElementName")] public SomeInfo<int> SomeInfo { get; set; } }
And then:
class Program { static void Main() { var model = new SomeModel { SomeString = new SomeInfo<string> { Value = "testData" }, SomeInfo = new SomeInfo<int> { Value = 5 } }; var serializer = new XmlSerializer(model.GetType()); serializer.Serialize(Console.Out, model); } }
will produce:
<?xml version="1.0" encoding="ibm850"?> <SomeModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SomeStringElementName Value="testData" /> <SomeInfoElementName Value="5" /> </SomeModel>
Kind of, use the XmlAttribute
instead of XmlElement
, but it won't look like what you want. It will look like the following:
<SomeModel SomeStringElementName="testData"> </SomeModel>
The only way I can think of to achieve what you want (natively) would be to have properties pointing to objects named SomeStringElementName and SomeInfoElementName where the class contained a single getter named "value". You could take this one step further and use DataContractSerializer so that the wrapper classes can be private. XmlSerializer won't read private properties.
// TODO: make the class generic so that an int or string can be used. [Serializable] public class SerializationClass { public SerializationClass(string value) { this.Value = value; } [XmlAttribute("value")] public string Value { get; } } [Serializable] public class SomeModel { [XmlIgnore] public string SomeString { get; set; } [XmlIgnore] public int SomeInfo { get; set; } [XmlElement] public SerializationClass SomeStringElementName { get { return new SerializationClass(this.SomeString); } } }
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