Per visualizzare l'articolo in inglese, selezionare la casella di controllo Inglese. È possibile anche visualizzare il testo inglese in una finestra popup posizionando il puntatore del mouse sopra il testo.
Traduzione
Inglese

NIB: caratteri di una coppia di surrogati in un documento XML

Un surrogato o una coppia di surrogati è una coppia di valori di codifica Unicode a 16 bit che, assieme, rappresentano un carattere singolo. È importante ricordare che le coppie di surrogati sono effettivamente caratteri singoli a 32 bit, e non è più possibile presupporre che il mapping di un valore di codifica Unicode a 16 bit corrisponda esattamente a un solo carattere.

Il primo valore della coppia di surrogati è il carattere surrogato alto e contiene un valore di codifica a 16 bit compreso nell'intervallo tra U+D800 e U+DBFF. Il secondo valore della coppia, il carattere surrogato basso, contiene valori compresi nell'intervallo tra U+DC00 e U+DFFF. Utilizzando le coppie di surrogati, il sistema di codifica Unicode a 16 bit è in grado di indirizzare oltre un milione di caratteri (220) aggiuntivi, definiti dallo standard Unicode.

È possibile utilizzare i caratteri surrogati in qualsiasi stringa passata a un metodo XmlTextWriter. Tuttavia, è necessario che il carattere surrogato sia valido nell'XML scritto. La raccomandazione W3C (World Wide Web Consortium), ad esempio, non consente caratteri surrogati all'interno dei nomi di elementi o di attributi. Se la stringa contiene una coppia di surrogati non valida, verrà generata un'eccezione.

Inoltre, è possibile utilizzare il metodo WriteSurrogateCharEntity per scrivere l'entità del carattere corrispondente a una coppia di surrogati. L'entità del carattere viene scritta in formato esadecimale e viene generata con la formula:

(highChar -0xD800) * 0x400 + (lowChar -0xDC00) + 0x10000

Se la stringa contiene una coppia di surrogati non valida, verrà generata un'eccezione. Nell'esempio seguente viene illustrato il metodo WriteSurrogateCharEntity con una coppia di surrogati come input.

// The following line writes &#x10000.
WriteSurrogateCharEntity ('\uDC00', '\uD800');

Nell'esempio seguente viene generato un file della coppia di surrogati, che viene caricato nel tipo XmlReader e salvato con un nuovo nome.Il file originale e quello nuovo vengono poi caricati nuovamente nell'applicazione nella struttura DOM XML per eseguire un confronto.

char lowChar, highChar;
char [] charArray = new char[10];
FileStream targetFile = new FileStream("SurrogatePair.xml",
      FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);

lowChar = Convert.ToChar(0xDC00);
highChar = Convert.ToChar(0xD800);
XmlTextWriter tw = new XmlTextWriter(targetFile, null);
tw.Formatting = Formatting.Indented;
tw.WriteStartElement("root");
tw.WriteStartAttribute("test", null);
tw.WriteSurrogateCharEntity(lowChar, highChar);
lowChar = Convert.ToChar(0xDC01);
highChar = Convert.ToChar(0xD801);
tw.WriteSurrogateCharEntity(lowChar, highChar);
lowChar = Convert.ToChar(0xDFFF);
highChar = Convert.ToChar(0xDBFF);
tw.WriteSurrogateCharEntity(lowChar, highChar);

// Add 10 random surrogate pairs.
// As Unicode, the high bytes are in lower
// memory; for example, word 6A21 as 21 6A.
// The high or low is in the logical sense.
Random random = new Random();
for (int i = 0; i < 10; ++i) {
      lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));
      highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));
      charArray[i] = highChar;
      charArray[++i] = lowChar;
}
tw.WriteChars(charArray, 0, charArray.Length);

for (int i = 0; i < 10; ++i) {
      lowChar = Convert.ToChar(random.Next(0xDC00, 0xE000));
      highChar = Convert.ToChar(random.Next(0xD800, 0xDC00));
      tw.WriteSurrogateCharEntity(lowChar, highChar);
}

tw.WriteEndAttribute();
tw.WriteEndElement();
tw.Flush();
tw.Close();

XmlTextReader r = new XmlTextReader("SurrogatePair.xml");

r.Read();
r.MoveToFirstAttribute();
targetFile = new FileStream("SurrogatePairFromReader.xml",
       FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);

tw = new XmlTextWriter(targetFile, null);
tw.Formatting = Formatting.Indented;
tw.WriteStartElement("root");
tw.WriteStartAttribute("test", null);
tw.WriteString(r.Value);
tw.WriteEndAttribute();
tw.WriteEndElement();
tw.Flush();
tw.Close();

// Load both result files into the DOM and compare.
XmlDocument doc1 = new XmlDocument();
XmlDocument doc2 = new XmlDocument();
doc1.Load("SurrogatePair.xml");
doc2.Load("SurrogatePairFromReader.xml");
if (doc1.InnerXml != doc2.InnerXml) {
      Console.WriteLine("Surrogate Pair test case failed");
}

Quando si scrive utilizzando il metodo WriteChars, che consente di scrivere un buffer di dati alla volta, è possibile che una coppia di surrogati nell'input venga erroneamente divisa in un buffer.Poiché i valori surrogati sono ben definiti, se il metodo WriteChars rileva un valore Unicode dell'intervallo inferiore o di quello superiore, identifica tale valore come una metà della coppia di surrogati.Quando si verifica la situazione in cui il metodo WriteChars provocherebbe una scrittura dal buffer che divide una coppia di surrogati, viene generata un'eccezione.Utilizzare il metodo IsHighSurrogate per verificare se il buffer termina con un carattere surrogato alto.Se l'ultimo carattere del buffer non è un carattere surrogato alto, è possibile passare il buffer al metodo WriteChars.

Mostra: