2013-01-24 3 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 클래스를 작성해야합니까? 데이터베이스에서 날짜별로 데이터를 가져오고 있습니다. from 및 to 속성을 클래스의 속성으로 추가 할 수 있지만 value1, value2 ... 속성을 동적으로 추가 할 수 있습니까?

편집 :

는 나는 사전을 직렬화하는 방법을 발견 한 후 지금은 조금 더 가까이입니다. 여기에 내가 시도 것입니다 : I에게 지금

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

단지 :이 내가이처럼 보이는 XML을 얻을 것이다 사용

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 

: 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

나는 지금 당장 살 수 있다고 생각하거나 적어도 충분할지를 알기 위해 노력할 해결책이 있기 때문에 내 자신의 질문에 대답하려고합니다. 따라서 노드를 작성하고 나는이처럼 보이는 클래스 만든 그들에게 동적 속성을 추가 : 내가 예를 들어 내 XML 객체에서이 클래스를 사용할 수 있습니다

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 

: 다음

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

과 다음과 같은 예를 들어 코드에서 객체를 생성 :

,536 :

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> 

이제 충분히 가까워서 이것으로 작업 할 수 있다고 생각합니다. 누구든지 아이디어가 있다면 나는 그 이야기를 듣기보다 행복 할 것입니다.

관련 문제