Condividi tramite


Definire la serializzazione di dati XML

Si applica a:SQL ServerDatabase SQL di AzureIstanza gestita di SQL di Azure

Quando si esegue il cast esplicito o implicito del tipo di dati xml a un tipo SQL stringa o binario, il contenuto del tipo di dati xml verrà serializzato in base alle regole illustrate in questo articolo.

Codifica della serializzazione

Se il tipo SQL di destinazione è VARBINARY, il risultato viene serializzato nel formato UTF-16 preceduto da un indicatore dell'ordine dei byte UTF-16, ma senza una dichiarazione XML. Se il tipo di destinazione è di grandezza troppo ridotta, viene generato un errore.

Ad esempio:

select CAST(CAST(N'<Δ/>' as XML) as VARBINARY(MAX))

Risultato:

0xFFFE3C0094032F003E00

Se il tipo SQL di destinazione è NVARCHAR o NCHAR, il risultato viene serializzato nel formato UTF-16 non preceduto dall'indicatore dell'ordine dei byte e senza una dichiarazione XML. Se il tipo di destinazione è di grandezza troppo ridotta, viene generato un errore.

Ad esempio:

select CAST(CAST(N'<Δ/>' as XML) as NVARCHAR(MAX))

Risultato:

<Δ/>

Se il tipo di destinazione SQL è VARCHAR o CHAR, il risultato viene serializzato nella codifica corrispondente alla tabella codici delle regole di confronto del database, senza un indicatore dell'ordine dei byte o una dichiarazione XML. Se il tipo di destinazione è troppo piccolo o se non è possibile eseguire il mapping del valore alla pagina codice di confronto di destinazione, viene sollevato un errore.

Ad esempio:

select CAST(CAST(N'<Δ/>' as XML) as VARCHAR(MAX))

È possibile che venga generato un errore se la pagina di codice delle regole di confronto corrente non è in grado di rappresentare il carattere Unicode Δ, oppure verrà rappresentato nella codifica specifica.

Per la restituzione dei risultati XML al lato client, i dati verranno inviati con la codifica UTF-16. Il provider sul lato client esporrà quindi i dati in base alle regole delle relative API.

Serializzazione delle strutture XML

Il contenuto di un tipo di dati xml viene serializzato nel modo standard. In particolare, i nodi elemento sono mappati al markup dell'elemento, e i nodi di testo sono mappati al contenuto testuale. Nelle sezioni seguenti vengono tuttavia illustrate le situazioni in cui i caratteri vengono sostituiti con entità e le modalità di serializzazione dei valori atomici tipizzati.

Entitizzazione dei caratteri XML durante la serializzazione

Ogni struttura XML serializzata dovrebbe essere in grado di essere riparsa. La serializzazione di alcuni caratteri deve pertanto prevedere la sostituzione con entità, per mantenere la possibilità del round-trip dei caratteri durante la fase di normalizzazione del parser XML. Tuttavia, alcuni caratteri devono essere trasformati in entità affinché il documento sia ben formato e, quindi, possa essere elaborato. Di seguito sono descritte le regole di entitizzazione che si applicano durante la serializzazione.

  • I caratteri &, < e > vengono sempre sostituiti rispettivamente con le entità &amp;, &lt; e &gt; se sono presenti in un valore di attributo o nel contenuto di un elemento.

  • Poiché SQL Server utilizza le virgolette doppie (U+0022) per racchiudere i valori degli attributi, la virgoletta nei valori degli attributi viene convertita nell'entità &quot;.

  • Una coppia di surrogati viene codificata come un singolo riferimento numerico a caratteri, quando il cast viene effettuato esclusivamente sul server. Ad esempio la coppia di surrogati U+D800 U+DF00 viene sostituita dall'entità rappresentata dal riferimento al carattere numerico &#x00010300;.

  • Per evitare che una tabulazione TAB (U+0009) e un avanzamento di riga (LF, U+000A) vengano normalizzati durante l'analisi, vengono sostituiti con le entità rappresentate dai relativi riferimenti a caratteri numerici, rispettivamente &#x9; e &#xA;, all'interno dei valori di attributo.

  • Per evitare che un ritorno carrello (CR, U+000D) venga normalizzato durante l'analisi, viene convertito nel suo riferimento numerico, &#xD; sia nei valori degli attributi sia nei contenuti degli elementi.

  • Per proteggere i nodi di testo che contengono solo spazi vuoti, uno degli spazi vuoti (in genere l'ultimo) viene sostituito con l'entità rappresentata dal relativo riferimento a un carattere numerico. In questo modo, durante l'analisi il nodo di testo con spazi vuoti viene mantenuto, indipendentemente da come vengono gestiti gli spazi vuoti durante l'analisi.

Ad esempio:

DECLARE @u NVARCHAR(50)
set @u = N'<a a="
    '+NCHAR(0xD800)+NCHAR(0xDF00)+N'>">   '+NCHAR(0xA)+N'</a>'
SELECT CAST(CONVERT(XML,@u,1) as NVARCHAR(50));

Risultato:

<a a="
    𐌀>">
</a>

Se non si vuole applicare l'ultima regola di protezione relativa agli spazi vuoti, è possibile usare l'opzione esplicita CONVERT 1 quando si esegue il cast dal tipo xml a un tipo string o binary. Ad esempio, per evitare l'entitizzazione, puoi fare quanto segue:

SELECT CONVERT(NVARCHAR(50), CONVERT(XML, '<a>   </a>', 1), 1);

Il metodo query() (tipo di dati xml) restituisce un'istanza del tipo di dati xml. Qualsiasi risultato del metodo query() per cui viene eseguito il cast a un tipo stringa o binario viene pertanto entitizzato in base alle regole descritte in precedenza. Se vuoi ottenere i valori stringa che non sono convertiti in entità, dovresti usare invece il metodo value() (tipo di dati xml). Di seguito è riportato un esempio d'uso del metodo query():

DECLARE @x xml
SET @x = N'<a>This example contains an entitized char: .</a>'
SELECT @x.query('/a/text()');

Risultato:

This example contains an entitized char: .

Di seguito è riportato un esempio d'uso del metodo value():

SELECT @x.value('(/a/text())[1]', 'nvarchar(100)');

Risultato:

This example contains an entitized char: .

Serializzazione di un tipo di dati xml tipizzato

Un'istanza di un tipo di dati xml tipizzato contiene valori tipizzati in base ai relativi tipi XML Schema. Tali valori vengono serializzati in base al loro tipo di schema XML, nello stesso formato generato dal cast di XQuery a xs:string. Per altre informazioni, vedere Regole di conversione dei tipi in XQuery.

Ad esempio, il valore xs:double 1.34e1 viene serializzato in 13.4, come illustrato nell'esempio seguente:

declare @x xml
set @x =''
select CAST(@x.query('1.34e1') as nvarchar(50));

Viene restituito il valore stringa 13.4.

Vedi anche