2009-07-22 81 views
4

我正在序列化一個包含String屬性中的HTML數據的對象。包含無效字符的對象的XML序列化

Dim Formatter As New Xml.Serialization.XmlSerializer(GetType(MyObject)) 
Dim fs As New FileStream(FilePath, FileMode.Create) 
Formatter.Serialize(fs, Ob) 
fs.Close() 

但是,當我在看XML回對象:

Dim Formatter As New Xml.Serialization.XmlSerializer(GetType(MyObject)) 
Dim fs As New FileStream(FilePath, FileMode.Open) 
Dim Ob = CType(Formatter.Deserialize(fs), MyObject) 
fs.Close() 

我得到這個錯誤:

"'', hexadecimal value 0x14, is an invalid character. Line 395, position 22." 

不應該.NET防止這種錯誤的,轉義無效字符?

這裏發生了什麼,我該如何解決?

回答

2

它應該真的在序列化步驟失敗,因爲0x14 is an invalid value for XML無法轉義它,即使使用&#x14也無法逃避它,因爲它被排除爲XML模型中的有效字符。序列化程序讓我們感到驚訝,因爲它使得序列化程序不合規。

是否可以在序列化之前從字符串中刪除無效字符?爲了什麼目的,你在HTML中有一個0x14

或者,您是否可以使用一種編碼進行編寫,然後使用另一種編碼進行閱讀?

+0

嗯,我已經走了這個解決方案。在序列化之前,我從字符串中刪除了無效字符。但是,我仍然不明白爲什麼不XmlSerializer反序列化已序列化的對象。 – InfoStatus 2009-07-22 18:18:10

+0

您的狀態良好,除非無效字符非常重要。 – 2009-07-22 18:36:51

+1

我在這裏發現了這個問題的更全面的描述:http://seattlesoftware.wordpress.com/2008/09/11/hexadecimal-value-0-is-an-invalid-character/ – Derrick 2011-01-10 15:19:50

0

我會怎樣exepct .NET來處理這個問題,但你也可以看看XmlSerializer類和XmlReaderSettings(見下面的示例通用方法):

public static T Deserialize<T>(string xml) 
{ 
    var xmlReaderSettings = new XmlReaderSettings() 
           { 
            ConformanceLevel = ConformanceLevel.Fragment, 
            ValidationType = ValidationType.None 
           }; 

    XmlReader xmlReader = XmlTextReader.Create(new StringReader(xml), xmlReaderSettings); 
    XmlSerializer xs = new XmlSerializer(typeof(T), ""); 

    return (T)xs.Deserialize(xmlReader); 
} 

我還要檢查是否有沒有編碼(統一,UTF8等)問題。十六進制值0x14不是您期望的XML中的字符:)

1

您應該真正發佈您嘗試序列化和反序列化的類的代碼。同時,我會猜測。

很可能,無效字符位於string類型的字段或屬性中。您需要序列化的字節數組,假設你不能避免該角色目前在所有:

[XmlRoot("root")] 
public class HasBase64Content 
{ 
    internal HasBase64Content() 
    { 
    } 

    [XmlIgnore] 
    public string Content { get; set; } 

    [XmlElement] 
    public byte[] Base64Content 
    { 
     get 
     { 
      return System.Text.Encoding.UTF8.GetBytes(Content); 
     } 
     set 
     { 
      if (value == null) 
      { 
       Content = null; 
       return; 
      } 

      Content = System.Text.Encoding.UTF8.GetString(value); 
     } 
    } 
} 

這將產生XML這樣的:

<?xml version="1.0" encoding="utf-8"?> 
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Base64Content>AAECAwQFFA==</Base64Content> 
</root> 

我看你可能更喜歡VB.NET:

''# Prettify doesn't like attributes as the first item in a VB code block, so this comment is here so that it looks right on StackOverflow. 
<XmlRoot("root")> _ 
Public Class HasBase64Content 

    Private _content As String 
    <XmlIgnore()> _ 
    Public Property Content() As String 
     Get 
      Return _content 
     End Get 
     Set(ByVal value As String) 
      _content = value 
     End Set 
    End Property 

    <XmlElement()> _ 
    Public Property Base64Content() As Byte() 
     Get 
      Return System.Text.Encoding.UTF8.GetBytes(Content) 
     End Get 
     Set(ByVal value As Byte()) 
      If Value Is Nothing Then 
       Content = Nothing 
       Return 
      End If 
      Content = System.Text.Encoding.UTF8.GetString(Value) 
     End Set 
    End Property 
End Class 
6

我集T他將XmlReaderSettings屬性的CheckCharacters設置爲false。 我只會建議這樣做,如果你已經通過XmlSerializer自己序列化數據。如果來自未知來源,那麼這不是一個好主意。

public static T Deserialize<T>(string xml) 
{ 
    var xmlReaderSettings = new XmlReaderSettings() { CheckCharacters = false }; 

    XmlReader xmlReader = XmlTextReader.Create(new StringReader(xml), xmlReaderSettings); 
    XmlSerializer xs = new XmlSerializer(typeof(T)); 

    return (T)xs.Deserialize(xmlReader); 
} 
相關問題