2017-01-20 6 views
1

クラスを表すXML要素を1つの文字列に減らすにはどうすればよいですか?私のXMLシリアライザの出力この:XMLをクラス全体にシリアライズ

<ArrayOfCity> 
    <City> 
    <Name>Los Angeles</Name> 
    <Location> 
     <Value>034.050N -118.250E</Value> 
    </Location> 
    <Elevation>305</Elevation> 
    <Population>3884000</Population> 
    </City> 
    <City> 
    <Name>New York</Name> 
    <Location> 
     <Value>040.713N -074.006E</Value> 
    </Location> 
    <Elevation>33</Elevation> 
    <Population>8550405</Population> 
    </City> 
</ArrayOfCity> 

しかし、私はそれがこの(簡体字<Location>要素)のようになりたい:

<ArrayOfCity> 
    <City> 
    <Name>Los Angeles</Name> 
    <Location>034.050N -118.250E</Location> 
    <Elevation>305</Elevation> 
    <Population>3884000</Population> 
    </City> 
    <City> 
    <Name>New York</Name> 
    <Location>040.713N -074.006E</Location> 
    <Elevation>33</Elevation> 
    <Population>8550405</Population> 
    </City> 
</ArrayOfCity> 

私のクラスの実装は、次のとおりです。

Public Class City 
    Public Property Name As String 
    Public Property Location As LatLong 
    Public Property Elevation As Integer 
    Public Property Population As Integer 

    Public Overrides Function ToString() As String 
     Return Name 
    End Function 
End Class 

Public Class LatLong 
    Implements ISerializable 

    <XmlIgnore()> 
    Private _Lat As Single 
    <XmlIgnore()> 
    Private _Long As Single 

    <XmlIgnore()> 
    Public Property Latitude As Single 
     Get 
      Return _Lat 
     End Get 
     Set(value As Single) 
      _Lat = value 
     End Set 
    End Property 

    <XmlIgnore()> 
    Public Property Longitude As Single 
     Get 
      Return _Long 
     End Get 
     Set(value As Single) 
      _Long = value 
     End Set 
    End Property 

    Public Property Value As String 
     Get 
      Return String.Format("{0:000.000}N {1:000.000}E", Latitude, Longitude) 
     End Get 
     Set(value As String) 
      'Pos Value: N & E, Neg Value: S & W 
      'Format must be [###.###N ###.###E] (spacing and digits can be variable, but cannot use S or W) 
      _Lat = CSng(Split(value, "N")(0)) 
      _Long = CSng(Split(value.Replace("E", ""), "N")(1)) 
     End Set 
    End Property 

    Public Sub New() 
     _Lat = 0 
     _Long = 0 
    End Sub 

    Public Sub New(InitialString As String) 
     Value = InitialString 
    End Sub 

    Public Overrides Function ToString() As String 
     Return Value 
    End Function 

    Public Shared Widening Operator CType(ByVal O As String) As LatLong 
     Return New LatLong(O) 
    End Operator 

    Public Shared Narrowing Operator CType(O As LatLong) As String 
     Return O.ToString 
    End Operator 

    Public Overrides Function Equals(obj As Object) As Boolean 
     With DirectCast(obj, LatLong) 
      Return Latitude = .Latitude AndAlso Longitude = .Longitude 
     End With 
    End Function 

    Public Shared Operator =(Left As LatLong, Right As LatLong) As Boolean 
     Return Left.Equals(Right) 
    End Operator 

    Public Shared Operator <>(Left As LatLong, Right As LatLong) As Boolean 
     Return Not Left.Equals(Right) 
    End Operator 

    Protected Sub New(info As SerializationInfo, context As StreamingContext) 
     'Value = DirectCast(info.GetValue("props", GetType(String)), String) 
    End Sub 

    Public Sub GetObjectData(info As SerializationInfo, context As StreamingContext) Implements ISerializable.GetObjectData 
     Throw New NotImplementedException() 
    End Sub 
End Class 

私はかなりよキーがProtected Sub New(...)Public Sub GetObjectData(...)にあることを確認してくださいが、わかりません。判断できる場合は、XMLエレメントのプロパティで最もよく使用されます。

ありがとうございました!

更新日: 私はそれを理解しました。 LatLongブログのクラスは、IXmlSerializableとのWriteXML(...)とReadXmlの説明(...)潜水艦はこのように実装する必要が実装する必要があります:

Public Sub ReadXml(reader As XmlReader) Implements IXmlSerializable.ReadXml 
    Value = reader.ReadElementContentAsString 
End Sub 

Public Sub WriteXml(writer As XmlWriter) Implements IXmlSerializable.WriteXml 
    writer.WriteString(Value) 
End Sub 
+0

あなただけの表面位置の値ならば、あなたはLatLong'として非直列化された '公共財産の場所としての場所をマークして導入することができます'Location.Value'を取る別のプロパティ –

+0

ありがとうございました!私は実際にその考えを持っていました。しかし、複雑なデータ型であるプロパティごとに2つのメンバを持つ必要はありません。私が投稿したのは質問を伝えるために開発した例ですが、私の実際のプロジェクトでは文字列に絞ることができるクラスが数多くあり、私はきれいなソリューションを探していました。私はそれがコメントでなければ答えとしてマークしています... :) –

+0

まあ。どれどれ。シリアル化ロジックをAPIロジックから分離することができます。 'CitySerialized'という2番目のクラスを作成し、' City' - 'ToSerialized/FromSerialized'のいくつかの拡張を開発し、必要に応じて' arrayOfCities.select(function(x)x.ToSerialized()) 'を呼び出してそれを直列化します。つまり、私はあなたがこれを行う文脈を知らないのです。 –

答えて

0

LatLongブログのクラスは、IXmlSerializableとのWriteXMLを(実装する必要があります。.. 。)とReadXmlの説明(...)潜水艦は、次のように実装する必要があります

Public Sub ReadXml(reader As XmlReader) Implements IXmlSerializable.ReadXml 
    Value = reader.ReadElementContentAsString 
End Sub 

Public Sub WriteXml(writer As XmlWriter) Implements IXmlSerializable.WriteXml 
    writer.WriteString(Value) 
End Sub 
関連する問題