I am creating an XML with serialization and I have a problem when I need to create attributes dynamically to an element. I am adding elements of dates that have a price data in them. My class structure for the XML looks like this:
<XmlRoot(ElementName:="root")>
Public Class DateXML
<XmlElement(ElementName:="date")> _
Public Property Dates As List(Of DatePrice)
End Class
Public Class DatePrice
<XmlAttribute("value")> _
Public Property DateValue As String
<XmlElement("price")> _
Public Property Price As String
End Class
The XML will then look like this for example:
<root>
<date value="2013-01-01">
<price>100.00</price>
</date>
<date value="2013-01-02">
<price>100.00</price>
</date>
<date value="2013-01-03">
<price>100.00</price>
</date>
<date value="2013-01-04">
<price>100.00</price>
</date>
<date value="2013-01-08">
<price>100.00</price>
</date>
<date value="2013-01-12">
<price>100.00</price>
</date>
</root>
My problem is with a requirement for the XML. If I have multiple date values with the same price I should put them in one node using value1="2013-01-01" value2="2013-01-02" etc. Additionally if the dates follow each other I should use from="" to="" attributes and I am allowed to mix these attributes. The goal is to create as few of the date nodes as possible using attributes. So the example above should be something like this:
<root>
<date from="2013-01-01" to="2013-01-04">
<price>100.00</price>
</date>
<date value1="2013-01-08" value2="2013-01-12">
<price>100.00</price>
</date>
</root>
How should I create my DatePrice class to accomplish this requirement? I am getting the data per date from the database. I could add the from and to attributes as a properties to the class but is it possible to add attributes dynamically for the value1, value2…?
EDIT:
I’m a bit closer now after discovering how to serialize an dictionary. Here is what I have tried:
<XmlRoot(ElementName:="root")>
Public Class XmlObject
<XmlElement(ElementName:="element")> _
Public Property element As String
Public Property elementAttributes As ValueAttributes
End Class
Public Class ValueAttributes
Public Property values As SerializableDictionary(Of String, String)
End Class
Dictionary class that implements IXmlSerializable:
Public Class SerializableDictionary(Of AttributeName, AttributeValue)
Inherits Dictionary(Of String, String)
Implements IXmlSerializable
Public Function GetSchema() As System.Xml.Schema.XmlSchema Implements System.Xml.Serialization.IXmlSerializable.GetSchema
Return Nothing
End Function
Public Sub ReadXml(reader As System.Xml.XmlReader) Implements System.Xml.Serialization.IXmlSerializable.ReadXml
If reader.HasAttributes Then
While reader.MoveToNextAttribute()
Dim key As String = reader.Name
Dim value As String = reader.Value
Me.Add(key, value)
End While
reader.MoveToElement()
End If
End Sub
Public Sub WriteXml(writer As System.Xml.XmlWriter) Implements System.Xml.Serialization.IXmlSerializable.WriteXml
For Each kvp As KeyValuePair(Of String, String) In Me
writer.WriteAttributeString(kvp.Key, kvp.Value)
Next
End Sub
End Class
Using these I’ll get an XML that looks like this:
<root>
<element>the element value</element>
<elementAttributes>
<values value1="1" value2="2" value3="3" />
</elementAttributes>
</root>
Now I just would need to somehow figure how to move the attributes to the element and not write the elementAttributes structure.
Going to answer my own question as I have a solution that I think I can live with for now or at least going to give it a try to see if it will be enough. So to create the nodes and add the attributes dynamically to them I have created a class that looks like this:
I can use this class in my xml object for example:
And then creating the object in code for example like this:
Will give a result XML that looks like this:
I think I am close enough now so I can work with this. If anyone have any ideas I would be more than happy to hear them.