在序列化/反序列化某些类时,我遇到了将某些属性标记或标记为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元素。
答案 0 :(得分:3)
两件事:
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只为整个类创建一次,并且不会污染类的私有名称空间。
2)序列化程序应该已正确转义字符数据。你真的需要它成为CData吗?您序列化的任何内容都应该正确反序列化以匹配原始内容,甚至是代码字符串之类的东西。我可以需要 CDATA部分的唯一情况是,如果你必须符合期望它的模式。
答案 1 :(得分:1)
我遇到了类似的问题 - 客户端需要来自Web服务的XML,其中的字符串包含在可怕的CData标签中,这是完全不必要的,但他们不想重新编码他们的客户端,所以我必须使我的XML符合。
我的工作方式是将我想要显示为CDATA的(字符串)属性重新键入我自己的自定义类型“XmlCDataString”。
然后我在该类型上实现了IXmlSerializable并推送了一些Narrowing和Widening转换运算符重载,以便属性仍然像Strings一样工作。
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
这对我有用!