Lettura del contenuto completo utilizzando i flussi di caratteri

I metodi ReadChars, ReadBinHex, ReadBase64 vengono utilizzati per la lettura di flussi di grandi dimensioni. La differenza sta nel fatto che il metodo ReadChars legge il testo così com'è (US-ASCII), il metodo ReadBase64 decodifica il testo codificato in Base64, mentre il metodo ReadBinHex decodifica i dati codificati in binhex. Queste operazioni sono utili se nell'XML è presente testo internazionale, immagini o video codificati.

Il funzionamento di questi metodi è descritto qui di seguito.

  • ReadChars, ReadBinHex e ReadBase64 sono disponibili solo su un elemento. Utilizzando questi metodi su altri tipi di nodi non viene eseguita alcuna operazione.
  • Viene restituito il contenuto effettivo dei caratteri del buffer. Non vi è alcun tentativo di risolvere entità, CDATA o qualsiasi altro tag all'interno del buffer. Viene restituito tutto ciò che si trova tra il tag iniziale e il tag finale, compresi gli eventuali tag, come se si stesse leggendo dal flusso.
  • Le impostazioni di normalizzazione non vengono rispettate. Non esiste normalizzazione.
  • ReadChars restituisce il valore "0" quando ha raggiunto la fine di un flusso di caratteri sul quale stava operando e il reader viene posizionato nello stesso punto come se l'applicazione avesse richiamato ReadInnerXml.
  • Tutti i metodi Read dell'attributo, come ReadAttributeValue, non eseguono alcuna operazione durante la lettura dal flusso con ReadChars.

Codice di esempio di ReadBase64:

Questo metodo consente di decodificare Base64 e di restituire i byte binari decodificati.

Dim str As String = "<ROOT>AQID</ROOT>"
Dim r As New XmlTextReader(New StringReader(str))

r.Read()
Dim buffer(1) As Byte
While r.ReadBase64(buffer, 0, 1) <> 0
   Console.Write(buffer(0))
End While
Console.WriteLine()

[C#]
string str = "<ROOT>AQID</ROOT>";
XmlTextReader r = new XmlTextReader(new StringReader(str));

r.Read();
byte[] buffer = new byte[1];
while(r.ReadBase64(buffer,0,1) != 0) {
   Console.Write(buffer[0]);
}
Console.WriteLine();

Un altro esempio di codice è riportato in XmlTextReader.ReadBase64.

Codice di esempio di ReadBinHex:

Si tratta dell'input "wellform.xml" dell'esempio di ReadBinHex.

wellform.xml

<dt:person xmlns:dt="urn1">
<name>Alice Smith</name>
<dt:address>123 Maple Street, Seattle, WA 98112</dt:address>
<phone>(206) 555-1234</phone>
<!-- The following element is optional -->
<comments>The lady with the overgrown lawn.</comments>
<dt:date>2000-07-06</dt:date>
<time>18:31:40</time>
<dt:BinHex>000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF</dt:BinHex>
<Base64>AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==</Base64>
</dt:person>

Questo metodo consente di decodificare BinHex e di restituire i byte binari decodificati.

Private Sub TestIncrementalReadBinHex()
   Dim xmlReader As New XmlTextReader("wellform.xml")
   Dim i As Integer
   Try
      Dim binhexlen As Integer = 0
      Dim binhex(1000) As Byte
      While xmlReader.Read()
         If "dt:BinHex" = xmlReader.Name Then
            Exit While
         End If
      End While
      binhexlen = xmlReader.ReadBinHex(binhex, 0, 50)
      For i = 0 To binhexlen - 1
         Console.Write(binhex(i))
      Next i
      While "dt:BinHex" = xmlReader.Name
         binhexlen = xmlReader.ReadBinHex(binhex, 0, 50)
         For i = 0 To binhexlen - 1
            Console.Write(binhex(i))
         Next i
      End While
      Console.WriteLine()
      xmlReader.Close()
   Catch e As Exception
      xmlReader.Close()
      Console.WriteLine(("Exception: " & e.Message))
      Return
   End Try
End Sub
[C#]
private void TestIncrementalReadBinHex() {       
   XmlTextReader xmlReader   = new XmlTextReader("wellform.xml");
   try {
      int binhexlen = 0;
      byte[] binhex = new byte[1000];
      while (xmlReader.Read()) {
         if ("dt:BinHex" == xmlReader.Name) break;
      }
      binhexlen = xmlReader.ReadBinHex(binhex, 0, 50);
      for (int i=0; i < binhexlen; i++) Console.Write(binhex[i]);
      while ("dt:BinHex" == xmlReader.Name) {
         binhexlen = xmlReader.ReadBinHex(binhex, 0, 50);
         for (int i=0; i < binhexlen; i++) Console.Write(binhex[i]);
      }
      Console.WriteLine();
      xmlReader.Close();
   }
   catch(Exception e) {
      xmlReader.Close();
      Console.WriteLine("Exception: " + e.Message);
      return;
   }
}

Un altro esempio di codice è riportato in XmlTextReader.ReadBinHex.

Esempio di ReadChars

Se ci si posiziona sul nodo dell'elemento Item nell'XML seguente:

<Item>test</Item>

ReadChars restituisce "test" e posiziona il reader sul nodo che segue </Item> EndElement. Dato questo input XML:

...
<small>
   <time>
      <days> 30 </days>
      <hours> 3 </hours>
      <minutes> 30 </minutes>
   </time>
</small>
<big>
...

eseguendo questo codice in base a esso, l'applicazione trova che una volta nel ciclo while, la posizione corrente è nel tag <small> e alla fine del ciclo, la posizione corrente è nel tag <big>:

If XmlNodeType.Element = reader.NodeType And "small" = reader.Name Then
   While 0 <> reader.ReadChars(buffer, 0, 1)
      ' Do something;
      ' reader is now positioned at <small>. Attribute values may not be
      ' available at this point. 
   End While 
End If
' At this point the Reader is positioned at <big > tag.
[C#]
if (XmlNodeType.Element == reader.NodeType && "small" == reader.Name) {
    while(0 != reader.ReadChars(buffer, 0, 1)) {
        // Do something;
        // reader is now positioned at <small>. Attribute values may not
       // be available at this point. 
    }
}
// At this point the Reader is positioned at <big > tag.

Se non si desidera leggere tutto fino alla fine di ReadChars, è possibile richiamare il metodo Read a metà della lettura e il reader verrà posizionato dopo l'elemento finale. Nel codice precedente, la chiamata avviene all'altezza del tag <big>.

Chiamate successive a ReadChars fanno avanzare il reader attraverso il testo. Nella tabella seguente è illustrato quanto accade, considerati i dati <Item>test</Item> e richiamando i metodi in successione.

Chiamate al metodo Risultati
Prima chiamata: ReadChars(buf, 0, 2) Restituisce 2 e buf contiene "te".
Seconda chiamata: ReadChars(buf, 0, 2) Restituisce 2 e buf contiene "st".
Terza chiamata: ReadChars(buf, 0, 2) Restituisce 0.

Il metodo ReadChars ignora i tag XML in formato non valido. Il seguente input XML, ad esempio, non ha un formato valido.

<A>a<A>g</A>

Se si utilizza il metodo ReadChars con questo input, viene restituito un markup solo per una coppia di tag, mentre gli altri markup vengono ignorati. Pertanto un metodo ReadChars eseguito con tale input restituisce:

a<A>g</A>

Vedere anche

Lettura dell'XML con XmlReader | Informazioni sulla dichiarazione del tipo di dati | Gestione dello spazio con XmlTextReader | Normalizzazione del valore degli attributi | Gestione delle eccezioni utilizzando XmlException in XmlTextReader | Classe XmlReader | Membri XmlReader | Classe XmlNodeReader | Membri XmlNodeReader | Classe XmlTextReader | Membri XmlTextReader | Classe XmlValidatingReader | XmlValidatingReader