Esecuzione di query su codice XML tramite OPENXML
La parola chiaveTransact-SQL OPENXML restituisce un set di righe simile a una tabella o una vista da documenti XML in memoria. OPENXML consente di accedere ai dati XML come se si trattasse di un set di righe relazionali, visualizzando la rappresentazione interna di un documento XML come un set di righe. I record del set di righe possono essere archiviati nelle tabelle del database.
È possibile utilizzare OPENXML nelle istruzioni SELECT e SELECT INTO ogni volta che i provider di set di righe, una vista o OPENROWSET possono comparire come origine. Per informazioni sulla sintassi di OPENXML, vedere OPENXML (Transact-SQL).
Per creare query su un documento XML tramite OPENXML, è innanzitutto necessario chiamare sp_xml_preparedocument, che analizza il documento XML e restituisce un handle al documento analizzato e pronto per l'utilizzo. Il documento analizzato è una rappresentazione dell'albero del modello di oggetti documento (DOM, Document Object Model) dei vari nodi inclusi nel documento XML. L'handle del documento viene quindi passato a OPENXML, che a sua volta visualizza il documento come un set di righe in base ai parametri passati.
Nota
A partire da SQL Server 2005, sp_xml_preparedocument utilizza una versione aggiornata da SQL del parser di MSXML, Msxmlsql.dll. Questa versione è stata progettata per supportare SQL Server e garantire la compatibilità con MSXML versione 2.6.
La rappresentazione interna di un documento XML deve essere rimossa dalla memoria tramite una chiamata alla stored procedure di sistema sp_xml_removedocument , in modo tale da liberare memoria.
Nella figura seguente è illustrato questo processo.
Si noti che per comprendere l'utilizzo di OPENXML, è necessario avere familiarità con le query XPath e XML. Per ulteriori informazioni sul supporto di XPath in SQL Server, vedere Utilizzo di query XPath in SQLXML 4.0.
Nota
OpenXML consente di parametrizzare i modelli XPath di riga e colonna come le variabili. La parametrizzazione può comportare attacchi intrusivi nelle espressioni XPath se viene esposta dal programmatore a utenti esterni, ad esempio se i parametri sono forniti tramite una stored procedure chiamata dall'esterno. Per evitare questi problemi potenziali di protezione, è consigliabile non esporre mai i parametri XPath a chiamanti esterni.
Parametri di OPENXML
I parametri passati a OPENXML includono:
L'handle di un documento XML (idoc).
Un'espressione XPath che identifica i nodi da mappare alle righe (rowpattern).
Una descrizione del set di righe da generare.
Il mapping tra le colonne del set di righe e i nodi XML.
Handle del documento XML (idoc)
L'handle del documento viene restituito dalla stored procedure sp_xml_preparedocument.
Espressione XPath che identifica i nodi da elaborare (rowpattern)
L'espressione XPath specificata come rowpattern identifica un set di nodi nel documento XML. Ogni nodo definito da rowpattern corrisponde a una riga specifica del set di righe generato da OPENXML.
I nodi definiti dall'espressione XPath possono essere qualsiasi nodo XML del documento XML. Se rowpattern identifica un set di elementi nel documento XML, a ogni nodo identificato corrisponderà una riga nel set di righe. Ad esempio, se rowpattern restituisce un attributo, verrà creata una riga per ogni nodo attributo selezionato da rowpattern.
Descrizione del set di righe da generare
OPENXML utilizza uno schema di set di righe per generare il set di righe risultante. Per specificare uno schema di set di righe, è possibile utilizzare le opzioni illustrate di seguito.
Utilizzo del formato di tabella edge
Per specificare uno schema di set di righe è consigliabile utilizzare il formato di tabella edge, evitando invece di utilizzare la clausola WITH.
In questo caso, OPENXML restituisce un set di righe nel formato di tabella edge. Il nome di questo formato deriva dal fatto che ogni margine dell'albero del documento XML analizzato viene mappato a una riga del set di righe.
In una tabella edge viene rappresentata la struttura dettagliata di un documento XML, che include i nomi degli elementi e degli attributi, la gerarchia del documento, gli spazi dei nomi e le istruzioni per l'elaborazione. Il formato di tabella edge consente di ottenere informazioni aggiuntive non esposte tramite le metaproprietà. Per ulteriori informazioni sulle metaproprietà, vedere l'argomento "Impostazione di metaproprietà in OPENXML".
Le informazioni aggiuntive disponibili in una tabella edge consentono di archiviare e di eseguire query sul tipo di dati di un elemento o di un attributo e sul tipo di nodo, di archiviare ed eseguire query sulle informazioni relative alla struttura del documento XML, nonché di creare un sistema di gestione dei documenti XML personalizzato.
Tramite una tabella edge è possibile scrivere stored procedure che accettano i documenti XML come input BLOB (Binary Large Object), generano la tabella edge e quindi estraggono e analizzano il documento al massimo livello di dettaglio (ricerca della gerarchia del documento, dei nomi di elementi e attributi, degli spazi dei nomi e delle istruzioni per l'elaborazione).
La tabella edge può inoltre fungere da formato di archiviazione per i documenti XML quando nessun altro tipo di mapping ad altri formati relazionali risulta appropriato e un campo ntext non restituisce informazioni strutturali sufficienti.
L'utilizzo di una tabella edge per analizzare un documento XML equivale a utilizzare un parser XML per ottenere le stesse informazioni.
Nella tabella seguente viene descritta la struttura della tabella edge.
Nome colonna |
Tipo di dati |
Descrizione |
---|---|---|
id |
bigint |
ID univoco del nodo del documento. Il valore dell'ID dell'elemento radice è 0. I valori di ID negativi sono riservati. |
parentid |
bigint |
Identifica il padre del nodo. Il padre identificato da questo ID non è necessariamente l'elemento padre, ma dipende dalla proprietà NodeType del nodo il cui padre è identificato da questo ID. Ad esempio, se il nodo è di tipo testo, il relativo padre potrebbe essere un nodo attributo. Se il nodo si trova al livello principale nel documento XML, il relativo valore ParentID è NULL. |
node type |
int |
Identifica il tipo di nodo ed è un intero che corrisponde alla numerazione del tipo di nodo DOM XML. Di seguito sono riportati i valori che indicano il tipo di nodo visualizzabili nella colonna: 1 = Nodo elemento 2 = Nodo attributo 3 = Nodo di testo 4 = Nodo sezione CDATA 5 = Nodo riferimento a entità 6 = Nodo entità 7 = Nodo istruzione di elaborazione 8 = Nodo di commento 9 = Nodo di documento 10 = Nodo tipo di documento 11 = Nodo frammento di documento 12 = Nodo di notazione Per ulteriori informazioni, vedere l'argomento relativo alla proprietà nodeType nella documentazione in linea di Microsoft XML (MSXML) SDK. |
localname |
nvarchar(max) |
Specifica il nome locale dell'elemento o dell'attributo ed è NULL se l'oggetto DOM non ha un nome. |
prefix |
nvarchar(max) |
Rappresenta il prefisso dello spazio dei nomi del nome del nodo. |
namespaceuri |
nvarchar(max) |
Rappresenta l'URI dello spazio dei nomi del nodo. Se il valore è NULL, non sono presenti spazi dei nomi. |
datatype |
nvarchar(max) |
Rappresenta il tipo di dati effettivo della riga dell'elemento o dell'attributo e in caso contrario è NULL. Il tipo di dati è derivato dalla definizione DTD inline o dallo schema inline. |
prev |
bigint |
Rappresenta l'ID XML dell'elemento di pari livello precedente. È NULL se non è presente alcun elemento diretto di pari livello precedente. |
text |
ntext |
Include il valore dell'attributo o il contenuto dell'elemento in formato testo oppure è NULL se la voce della tabella edge non richiede un valore. |
Utilizzo della clausola WITH per specificare una tabella esistente
È possibile utilizzare la clausola WITH per specificare il nome di una tabella esistente. A tale scopo, specificare il nome della tabella il cui schema può essere utilizzato da OPENXML per generare il set di righe.
Utilizzo della clausola WITH per specificare uno schema
È possibile utilizzare la clausola WITH per specificare uno schema completo. Quando si specifica lo schema del set di righe, si definiscono i nomi delle colonne e i rispettivi tipi di dati, nonché il mapping di tali colonne al documento XML.
È possibile specificare il modello di colonna utilizzando il parametro ColPattern nell'argomento SchemaDeclaration. Il modello di colonna specificato consente di mappare una colonna del set di righe al nodo XML identificato da rowpattern, nonché di determinare il tipo di mapping.
Se per una colonna non viene specificato il parametro ColPattern, la colonna del set di righe viene mappata al nodo XML con lo stesso nome, in base al mapping specificato dal parametro flags. Se viene impostato nell'ambito della specifica dello schema nella clausola WITH, il parametro ColPattern sarà tuttavia prioritario rispetto al mapping specificato dal parametro flags.
Mapping tra le colonne del set di righe e i nodi XML
Nell'istruzione OPENXML è inoltre possibile specificare facoltativamente il tipo di mapping (incentrato sugli attributi o sugli elementi) tra le colonne del set di righe e i nodi XML identificati da rowpattern. Questa informazione viene utilizzata per la trasformazione tra i nodi XML e le colonne del set di righe.
Per specificare il tipo di mapping è possibile procedere in due modi e inoltre utilizzare entrambi i sistemi:
Tramite il parametro flags.
Il mapping specificato dal parametro flags si basa sullo corrispondenza dei nomi, ovvero i nodi XML vengono mappati alle colonne del set di righe corrispondenti con lo stesso nome.
Tramite il parametro ColPattern.
Il parametro ColPattern, ovvero un'espressione XPath, viene specificato nell'ambito di SchemaDeclaration nella clausola WITH. Il mapping specificato dal parametro ColPattern sovrascrive il mapping specificato dal parametro flags.
Il parametro ColPattern consente di specificare il tipo di mapping, incentrato sugli attributi o sugli elementi, che sovrascrive o migliora il mapping predefinito indicato in flags.
Il parametro ColPattern viene specificato nei casi seguenti:
Se il nome di colonna nel set di righe è diverso dal nome dell'elemento o dell'attributo al quale è mappato. In questo caso, il parametro ColPattern consente di identificare il nome dell'elemento o dell'attributo XML al quale è mappata la colonna del set di righe.
Se si desidera mappare un attributo di una metaproprietà alla colonna. In questo caso, il parametro ColPattern consente di definire la metaproprietà alla quale viene mappata la colonna del set di righe. Per ulteriori informazioni sull'utilizzo delle metaproprietà, vedere Impostazione di metaproprietà in OPENXML.
I parametri flags e ColPattern sono entrambi facoltativi. Se non viene specificato un mapping, viene utilizzato il mapping incentrato sugli attributi, ovvero il valore predefinito del parametro flags.
Mapping incentrato sugli attributi
Se il parametro flags dell'istruzione OPENXML viene impostato su 1 (XML_ATTRIBUTES), viene definito un mapping incentrato sugli attributi. Se il parametro flags include XML_ ATTRIBUTES, il set di righe esposto restituisce o utilizza le righe nelle quali ogni elemento XML è rappresentato come una riga. Gli attributi XML sono mappati agli attributi definiti in SchemaDeclaration o restituiti da Tablename nella clausola WITH, in base alla corrispondenza dei nomi. La corrispondenza dei nomi indica che gli attributi XML con un nome specifico vengono archiviati in una colonna del set di righe con lo stesso nome.
Se il nome della colonna è diverso dal nome dell'attributo a cui è mappata la colonna, è necessario specificare il parametro ColPattern.
Se l'attributo XML è associato a un qualificatore dello spazio dei nomi, anche il nome della colonna del set di righe deve essere associato a un qualificatore.
Mapping incentrato sugli elementi
Se il parametro flags dell'istruzione OPENXML viene impostato su 2 (XML_ATTRIBUTES), viene definito un mapping incentrato sugli elementi. Pur essendo simile al mapping incentrato sugli attributi, questo tipo di mapping è caratterizzato dalle differenze seguenti:
In base alla corrispondenza dei nomi del mapping, ad esempio una colonna mappata a un elemento XML avente lo stesso nome, verranno selezionati i sottoelementi non complessi a meno che non venga specificato un modello dei livelli delle colonne. Nella fase di recupero dei dati, se il sottoelemento è complesso perché include altri sottoelementi, la colonna verrà impostata su NULL e i valori degli attributi dei sottoelementi verranno ignorati.
Nel caso di più sottoelementi con lo stesso nome, verrà restituito il primo nodo.