2

特定のクラスをシリアル化/逆シリアル化するとき、特定のプロパティに CDATA 要素としてフラグを立てたりマークしたりする必要があることに遭遇しました (その内容のため)。私は現在これを次のように処理しています:

    <XmlElement("MessageText")> _
    Public Property XmlContentLeft() As XmlCDataSection
        Get
            Dim doc As New XmlDataDocument()
            Dim cd As XmlCDataSection = doc.CreateCDataSection(Me.MessageText)
            Return cd
        End Get
        Set(ByVal value As XmlCDataSection)
            Me.MessageText = value.Value
        End Set
    End Property

    <XmlIgnore()> _
    Public Property MessageText() As String
        Get
            Return _messageText
        End Get
        Set(ByVal value As String)
            _messageText= value
        End Set
    End Property

これはうまく機能しますが、欠点もあります。CDATA 要素にしたいものに対して重複するプロパティがあり、これらのプロパティに対して追加のコードを記述する必要があります。

だから私の質問は、これを行うためのより良い方法があるかどうかです? クラスごとにカスタム スキーマやシリアル化ルーチンを作成する必要はありません。理想的なシナリオでは、これらのプロパティに属性を追加して、自動的に CDATA 要素として扱われるようにすることができます。

4

2 に答える 2

3

2つのこと:

1) 次のように、既存の CDATA コードを単純化できます。

<XmlElement("MessageText")> _
Public Property XmlContentLeft() As XmlCDataSection
    Get
        return GetCData(Me.MessageText)
    End Get
    Set(ByVal value As XmlCDataSection)
        Me.MessageText = value.Value
    End Set
End Property

' this method is re-usable by any property that needs CData
Private Function GetCData(ByVal value As String) As XmlCDataSection
    Static doc As New XmlDataDocument() 
    return doc.CreateCDataSection(value)
End Function

<XmlIgnore()> _
Public Property MessageText() As String
    Get
        Return _messageText
    End Get
    Set(ByVal value As String)
        _messageText= value
    End Set
End Property

もちろん、実際には投稿したコードよりも多くのコードがありますが、CData プロパティははるかに単純になっていることに注意してください。また、私の使用はStaticタイプミスや C# の間違いではありません。VB.Net には、Static関数でメンバーを作成するためのあまり知られていないキーワードがあります。このように、XmlDataDocument はクラス全体に対して 1 回だけ作成され、クラスのプライベート名前空間を汚染しません。

2) シリアライザはすでに文字データを適切にエスケープしているはずです。本当にCDataである必要がありますか? コード文字列のようなものであっても、シリアル化するものはすべて、元のものと一致するように適切に逆シリアル化する必要があります。CDATA セクションが必要になる唯一のケースは、それを期待しているスキーマに準拠する必要がある場合です。

于 2008-11-12T16:18:08.437 に答える
1

私は同様の問題を抱えていました.クライアントは、恐ろしいCDataタグでラップされた文字列を持つWebサービスからのXMLを必要としていました.

私が作業した方法は、CDATA として表示したい (文字列) プロパティを、独自のカスタム型 "XmlCDataString" に再入力することでした。

次に、その型に IXmlSerializable を実装し、いくつかの Narrowing および Widening 変換演算子のオーバーロードを押し込んで、プロパティが可能な限り String のように機能するようにしました。

Imports System.Xml.Serialization
Imports System.Xml
<Serializable()> _
Public Class XmlCDataString
  Implements IXmlSerializable

  Private _strValue As String = Nothing

  Public Sub New()

  End Sub

  Public Sub New(ByVal strValue As String)
    _strValue = strValue
  End Sub

  Public Property StringValue() As String
    Get
      Return _strValue
    End Get
    Set(ByVal value As String)
      _strValue = value
    End Set
  End Property

  Public Shared Widening Operator CType(ByVal strValue As String) As XmlCDataString
    Return New XmlCDataString(strValue)
  End Operator

  Public Shared Narrowing Operator CType(ByVal cdata As XmlCDataString) As String
    Return cdata.StringValue
  End Operator

  Public Function GetSchema() As System.Xml.Schema.XmlSchema Implements System.Xml.Serialization.IXmlSerializable.GetSchema
    Throw New NotImplementedException
  End Function

  Public Sub ReadXml(ByVal reader As System.Xml.XmlReader) Implements System.Xml.Serialization.IXmlSerializable.ReadXml
    ' TODO
  End Sub

  Public Sub WriteXml(ByVal writer As System.Xml.XmlWriter) Implements System.Xml.Serialization.IXmlSerializable.WriteXml
    Dim doc As XmlDocument
    Dim xmlCData As XmlCDataSection
    Dim serializer As XmlSerializer

    doc = New XmlDataDocument()
    xmlCData = doc.CreateCDataSection(_strValue)
    serializer = New XmlSerializer(GetType(XmlCDataSection))
    serializer.Serialize(writer, xmlCData)

  End Sub
End Class

次にCDataにシリアル化するプロパティは、次のように再入力する必要があります(例を使用):

Private _messageText As XmlCDataString  

Public Property MessageText() As XmlCDataString 
    Get 
        Return _messageText 
    End Get 
    Set(ByVal value As XmlCDataString) 
        _messageText= value 
    End Set 
End Property 

それは私のために働いた!

于 2010-10-08T11:28:09.480 に答える