2009-10-29 7 views
6

Mam obiekt, który serializuję do xml. Wygląda na to, że wartość w jednej z właściwości zawiera znak szesnastkowy 0x1E. Próbowałem ustawić właściwość Kodowanie XmlWriterSettings zarówno na "utf-16" i "unicode", ale nadal otrzymuję wyjątek:Radzenie sobie z niedozwolonymi znakami w XML przy użyciu C# .NET

wystąpił błąd podczas generowania dokumentu XML. ---> System.InvalidOperationException: Wystąpił błąd podczas generowania dokumentu XML. ---> System.ArgumentException: '', wartość szesnastkowa 0x1E, jest nieprawidłowym znakiem.

Czy istnieje sposób na umieszczenie tych znaków w pliku XML? Jeśli nie, czy istnieją inne postacie, które mogą powodować problemy?

+0

Proszę pokazać kod, który odtwarza problem. Jak możemy Ci pomóc, gdy nie wiemy, co robisz, aby spowodować problem? –

Odpowiedz

2

Można uciec, a następnie jak w przypadku HTML. 0x1E jest takie samo jak 30, więc po prostu zamień znak separatora rekordów na ciąg "& 30;" i powinno być OK.

+0

Hej ... Próbowałem go użyć, ale przeglądarki i czytniki XML wciąż odsyłają je jako nieprawidłowe znaki. Na przykład ten kod XML jest nieprawidłowy: " bbb  ccc' –

7

Zalecenie XML (aka Spec) http://www.w3.org/TR/2000/REC-xml-20001006 kontury, które znaki są niedozwolone i muszą być ocalałem


2,2 Postacie

[Definicja: analizowany podmiot zawiera tekst, ciąg znaków, który może reprezentują dane znaczników lub znaków.] [Definicja: Postać jest jednostką atomową tekstu określoną przez ISO/IEC 10646 [ISO/IEC 10646] (patrz także [ISO/IEC 10646-2000]). Legalne znaki to tabulacja, powrót karetki, wiersz i znaki prawne Unicode oraz ISO/IEC 10646. Wersje tych norm cytowane w A.1 ​​Normy referencyjne były aktualne w czasie przygotowywania tego dokumentu. Nowe znaki mogą być dodawane do tych standardów przez poprawki lub nowe wydania. W związku z tym procesory XML muszą akceptować dowolny znak w zakresie określonym dla Char. Zastosowanie "znaki zgodności", jak określono w sekcji 6.8 [Unicode] (patrz D21 w punkcie 3.6 [Unicode3]), nie jest zalecane.]

zakresu znaków

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

mechanizm kodowanie punktów kodu znaków do wzorców bitowych może się różnić w zależności od jednostki. Wszystkie procesory XML muszą akceptować kodowanie UTF-8 i UTF-16 o numerze 10646; mechanizmy sygnalizowania, który z nich jest używany, lub do wprowadzenia innych kodowań do gry, są omówione później, w 4.3.3 Kodowanie znaków w jednostkach.


1

XML jest formatem czytelnym dla człowieka, a niedrukowalne znaki kontrolne są zabronione. Można użyć kodów jednostek dziesiętnych, takich jak & # 30; do ich reprezentowania lub kodowania treści w bazie-64.

1

Ponieważ nie podałeś żadnych szczegółów, domyślam się, że Twoja własność ma typ System.String. Jeśli tak, to nie możesz serializować go tak jak jest. Zamiast tego należy szeregować je jako 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

wiem, jest to stara sprawa, ale znalazłem link i iam umieszczenie go tutaj, to będzie użyteczne, którzy natknąć to pytanie. To zadziałało dla mnie.

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

i kodu z tej witryny.(W przypadku, gdy witryna idzie w dół)

/// <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

Jeśli dane nie pozwalają znaków z Unicode Control Picture bloku, można zachować ludzką czytelność zastępując je dla znaków kontrolnych po serializacji iz powrotem po deserializacji.

Poniżej znajdują się znaki:

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

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

␠ ␡

Mam nadzieję, że renderują się w przeglądarce i edytorach. Nawet jeśli nie, są one legalne w XML.