2009-10-29 16 views
6

我有一個對象,我正在序列化爲xml。看來其中一個屬性中的值包含十六進制字符0x1E。我試過設置XmlWriterSettings的編碼屬性既「UTF-16」和「統一」,但我仍然得到一個異常拋出:使用C#.NET處理XML中的禁止字符

這裏是一個錯誤生成XML文檔。 ---> System.InvalidOperationException:生成XML文檔時發生錯誤。 ---> System.ArgumentException:'',十六進制值0x1E,是一個無效的字符。

有沒有什麼辦法讓這些字符進入xml?如果沒有,是否還有其他角色會導致問題?

+0

請顯示一些重現問題的代碼。當我們不知道你在做什麼來引發問題時,我們如何幫助你? – 2009-10-30 01:26:47

回答

2

你可以像HTML一樣逃避。 0x1E與十進制30相同,因此只需將您的記錄分隔符替換爲字符串「& 30;」應該沒問題。

+0

嘿...我試圖使用它,但瀏覽器和XML閱讀器仍將其重新發布爲無效字符。例如,這個XML是無效的:' bbb  ccc' – 2011-07-14 08:52:29

7

XML建議(又名SPEC)http://www.w3.org/TR/2000/REC-xml-20001006輪廓的字符是不允許的,必須被轉義


2.2性狀

[定義:解析實體包含文本,字符的序列,其可以代表標記或字符數據。] [定義:字符是由ISO/IEC 10646 [ISO/IEC 10646](另見[ISO/IEC 10646-2000])規定的文本原子單位。合法字符是製表符,回車符,換行符以及Unicode和ISO/IEC 10646的合法字符.A.1規範性引用文件中引用的這些標準的版本是本文檔編寫時的最新版本。新的字符可能會通過修訂或新版本添加到這些標準中。因此,XML處理器必須接受爲Char指定的範圍內的任何字符。這裏使用的 「兼容字符」,如在[Unicode的]的6.8節所定義(也見D21在[Unicode3]的第3.6節),不鼓勵。]

字符範圍

[2]  Char  ::=  #x9 | #xA | #xD | [#x20-#xD7FF] | 
      [#xE000-#xFFFD] | [#x10000-#x10FFFF]  
    /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */ 

的機構,用於將字符碼點編碼爲位模式可能因實體而異。所有的XML處理器必須接受10646的UTF-8和UTF-16編碼;後面將在4.3.3實體中的字符編碼中討論用於指示兩者中哪一個正在使用或用於引入其他編碼的機制。


1

XML是一種人類可讀的格式,不可打印的控制字符被禁止。您可以使用小數字符實體代碼,如來表示它們,或者base-64編碼內容。

1

既然你沒有提供任何細節,我會猜測你的財產是System.String類型。如果是這樣,那麼你不能按原樣序列化它。相反,你必須把它序列化作爲一個byte []:

[XmlRoot("root")] 
public class HasBase64Content 
{ 
    [XmlIgnore] 
    public string Content { get; set; } 

    [XmlElement("Content")] 
    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); 
     } 
    } 
} 
2

我知道這是一個老問題,但我找到了一個鏈接和IAM在這裏張貼,這將是誰遇到這個問題非常有用。它爲我工作。

http://seattlesoftware.wordpress.com/2008/09/11/hexadecimal-value-0-is-an-invalid-character/

,並從該網站的代碼。(在情況下,如果站點關閉)

/// <summary> 
/// Remove illegal XML characters from a string. 
/// </summary> 
public string SanitizeXmlString(string xml) 
{ 
if (xml == null) 
{ 
    throw new ArgumentNullException("xml"); 
} 

StringBuilder buffer = new StringBuilder(xml.Length); 

foreach (char c in xml) 
{ 
    if (IsLegalXmlChar(c)) 
    { 
     buffer.Append(c); 
    } 
} 

return buffer.ToString(); 
} 

/// <summary> 
/// Whether a given character is allowed by XML 1.0. 
/// </summary> 
public bool IsLegalXmlChar(int character) 
{ 
return 
(
    character == 0x9 /* == '\t' == 9 */   || 
    character == 0xA /* == '\n' == 10 */   || 
    character == 0xD /* == '\r' == 13 */   || 
    (character >= 0x20 && character <= 0xD7FF ) || 
    (character >= 0xE000 && character <= 0xFFFD ) || 
    (character >= 0x10000 && character <= 0x10FFFF) 
); 
} 
1

如果您的數據不允許從Unicode的Control Picture塊字符,你可以通過在反序列化代替他們在系列化控制字符,然後再返回保持可讀性。

下面是文字:

␀␁␂␃␄␅␆␇␈␉␊␋␌␍␎␏

␐␑␒␓␔␕␖␗␘␙␚␛␜␝␞␟

␠␡

希望它們在您的瀏覽器和編輯器中呈現。即使他們不這樣做,他們在XML中也是合法的。