Le présent article vous propose de savoir comment tabulariser un XML
générique sans pour autant connaître le nom des balises XML en
utilisant une requête SQL avec XPath et XQuery…
Tour repose en effet sur deux éléments du langage XPath :
- la fonction local-name qui permet de retourner le nom d’une balise.
- le caractère générique * qui retourne les noeuds de l’axe qui
ont un nom.
Démonstration
Création d’une table pour stockage de notre XML :
GO
CREATE TABLE T_XML
(XML_ID INT IDENTITY PRIMARY KEY,
XML_DATA XML);
GO
Insertion d’un document XML doté de 2 niveaux d’arborescence :
VALUES (
'<config>
<recovery_interval_min>0</recovery_interval_min>
<fill_factor_percent>100</fill_factor_percent>
<nested_triggers>0</nested_triggers>
<server_trigger_recursion>0</server_trigger_recursion>
<show_advanced_options>1</show_advanced_options>
<priority_boost>0</priority_boost>
<affinity_mask>119</affinity_mask>
<cost_threshold_for_parallelism>5</cost_threshold_for_parallelism>
<max_degree_of_parallelism>0</max_degree_of_parallelism>
<max_server_memory_MB>8192</max_server_memory_MB>
<query_governor_cost_limit>0</query_governor_cost_limit>
<backup_compression_default>0</backup_compression_default>
<optimize_for_ad_hoc_workloads>0</optimize_for_ad_hoc_workloads>
<Agent_XPs>1</Agent_XPs>
<SQL_Mail_XPs>0</SQL_Mail_XPs>
<Database_Mail_XPs>1</Database_Mail_XPs>
<SMO_and_DMO_XPs>1</SMO_and_DMO_XPs>
<Ole_Automation_Procedures>1</Ole_Automation_Procedures>
<xp_cmdshell>1</xp_cmdshell>
<Ad_Hoc_Distributed_Queries>0</Ad_Hoc_Distributed_Queries>
</config>'
);
Et voici maintenant la requête pour ce faire :
Txml.XMLdata.VALUE('fn:local-name(.)', 'NVARCHAR(256)') AS BALISE,
Txml.XMLdata.VALUE('.', 'NVARCHAR(256)') AS VALEUR
FROM T_XML AS X
OUTER APPLY X.XML_DATA.nodes('config/*') AS Txml(XMLdata);
Ce qui donne :
----------- ------------------------------------ ----------
1 recovery_interval_min 0
1 fill_factor_percent 100
1 nested_triggers 0
1 server_trigger_recursion 0
1 show_advanced_options 1
1 priority_boost 0
1 affinity_mask 119
1 cost_threshold_for_parallelism 5
1 max_degree_of_parallelism 0
1 max_server_memory_MB 8192
1 query_governor_cost_limit 0
1 backup_compression_default 0
1 optimize_for_ad_hoc_workloads 0
1 Agent_XPs 1
1 SQL_Mail_XPs 0
1 Database_Mail_XPs 1
1 SMO_and_DMO_XPs 1
1 Ole_Automation_Procedures 1
1 xp_cmdshell 1
1 Ad_Hoc_Distributed_Queries 0
Si votre XML comporte plusieurs niveaux, deux solutions…
1 – Atteindre tous les noeuds à tous les niveaux
Exemple
GO
INSERT INTO T_XML
VALUES '
<network>
<protocole>IP</protocole>
<ipv4>
<ip1>192</ip1>
<ip2>168</ip2>
<ip3>0 </ip3>
<ip4>44 </ip4>
</ipv4>
</network>');
Et dans ce cas, la requête doit atteindre tous les niveau à l’aide de //* :
Txml.XMLdata.VALUE('fn:local-name(.)', 'NVARCHAR(256)') AS BALISE,
Txml.XMLdata.VALUE('.', 'NVARCHAR(256)') AS VALEUR
FROM T_XML AS X
OUTER APPLY X.XML_DATA.nodes('//*') AS Txml(XMLdata)
Mais notez que les niveaux non feuille « concatène » tous les informations
----------- -------------- ------------------
1 network IP1921680 44
1 protocole IP
1 ipv4 1921680 44
1 ip1 192
1 ip2 168
1 ip3 0
1 ip4 44
2 – On peut obtenir chaque niveau séparément :
a – premier niveau
Txml.XMLdata.VALUE('fn:local-name(.)', 'NVARCHAR(64)') AS BALISE,
Txml.XMLdata.VALUE('.', 'NVARCHAR(256)') AS VALEUR
FROM T_XML AS X
OUTER APPLY X.XML_DATA.nodes('*') AS Txml(XMLdata);
b – second niveau
Txml.XMLdata.VALUE('fn:local-name(.)', 'NVARCHAR(64)') AS BALISE,
Txml.XMLdata.VALUE('.', 'NVARCHAR(256)') AS VALEUR
FROM T_XML AS X
OUTER APPLY X.XML_DATA.nodes('*/*') AS Txml(XMLdata);
d – 3e niveau
Txml.XMLdata.VALUE('fn:local-name(.)', 'NVARCHAR(64)') AS BALISE,
Txml.XMLdata.VALUE('.', 'NVARCHAR(256)') AS VALEUR
FROM T_XML AS X
OUTER APPLY X.XML_DATA.nodes('*/*/*') AS Txml(XMLdata);
Les résultats sont :
----------- --------------- ------------------
1 network IP1921680 44
XML_ID BALISE VALEUR
----------- --------------- ------------------
1 protocole IP
1 ipv4 1921680 44
XML_ID BALISE VALEUR
----------- --------------- ------------------
1 ip1 192
1 ip2 168
1 ip3 0
1 ip4 44
CQFD !
Expert S.G.B.D relationnelles et langage S.Q.L
Moste Valuable Professionnal Microsoft SQL Server
Société SQLspot : modélisation, conseil, formation,
optimisation, audit, tuning, administration SGBDR
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.
L’entreprise SQL Spot
Le site web sur le SQL et les SGBDR