2013-01-24 46 views
1

我正在使用序列化創建XML,並且當我需要動態地爲元素創建屬性時遇到問題。我正在添加具有價格數據的日期元素。我的XML類的結構是這樣的:那麼.NET使用XmlSerializer動態添加屬性到元素

<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 

XML將看起來像這樣的例子:

<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> 

我的問題是對XML的要求。如果我有多個具有相同價格的日期值,我應該使用value1="2013-01-01" value2="2013-01-02"等將它們放在一個節點中。此外,如果日期遵循對方,我應該使用from="" to=""屬性,並允許將這些屬性混合使用。目標是使用屬性儘可能少地創建日期節點。所以上面的例子應該是這樣的:

<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> 

我應該如何創建我的DatePrice類來完成此要求?我從數據庫中獲取每個日期的數據。我可以添加從和屬性作爲一個屬性的類,但是有可能爲value1,value2 ...動態添加屬性?

編輯:

現在我發現如何序列化的詞典後有點接近。這是我曾嘗試:

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 

使用這些我會得到看起來像這樣的XML:

<root> 
    <element>the element value</element> 
    <elementAttributes> 
    <values value1="1" value2="2" value3="3" /> 
    </elementAttributes> 
</root> 

現在我只

實現IXmlSerializable的
<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 

字典類將需要以某種方式計算如何將屬性移動到element而不寫入elementAttributes結構。

回答

0

要回答我自己的問題,因爲我有一個解決方案,我想我現在可以或者至少試着去看看它是否足夠。因此,要創建節點和動態添加的屬性給他們我已經創建了一個類,看起來像這樣:

Public Class DateElement 
    Implements IXmlSerializable 

    Public Property DateValueAttributes As Dictionary(Of String, String) 
    Public Property Price As String 

    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 
      DateValueAttributes = New Dictionary(Of String, String) 
      While reader.MoveToNextAttribute() 
       DateValueAttributes.Add(reader.Name, reader.Value) 
      End While 

      reader.MoveToElement() 
     End If 

     Dim wasEmpty As Boolean = reader.IsEmptyElement 
     reader.Read() 

     If wasEmpty Then 
      Return 
     End If 

     While reader.NodeType <> System.Xml.XmlNodeType.EndElement 
      reader.ReadStartElement("price") 
      Price = reader.ReadString() 
      reader.ReadEndElement() 
     End While 

     reader.ReadEndElement() 

    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.DateValueAttributes 
      writer.WriteAttributeString(kvp.Key, kvp.Value) 
     Next 

     If Price IsNot Nothing Then 
      writer.WriteStartElement("price") 
      writer.WriteString(Price) 
      writer.WriteEndElement() 
     End If 

    End Sub 
End Class 

我可以使用這個類在我的XML對象,例如:

<XmlRoot(ElementName:="root")> 
Public Class XmlObject 
    <XmlElement("date")> 
    Public Property [element] As DateElement 
End Class 

然後在代碼中創建對象的例子是這樣的:

Dim xml As New XmlObject() 
     xml.element = New DateElement() 
     xml.element.DateValueAttributes = New Dictionary(Of String, String) 
     xml.element.DateValueAttributes.Add("value1", "2013-01-01") 
     xml.element.DateValueAttributes.Add("value2", "2013-01-02") 
     xml.element.DateValueAttributes.Add("value3", "2013-01-03") 
     xml.element.Price = "100.00" 

會給出一個結果XML看起來像這樣:

<root> 
    <date value1="2013-01-01" value2="2013-01-02" value3="2013-01-03"> 
    <price>100.00</price> 
    </date> 
</root> 

我想我現在已經夠近了,所以我可以用這個工作。如果有人有任何想法,我會非常樂意聽到他們。