Analyse syntaxique du rapport SSRS sur la database ReportServer

Ceci est une partie supérieure du XML du rapport:

<Report xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns:cl="http://schemas.microsoft.com/sqlserver/reporting/2010/01/componentdefinition" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition"> <AutoRefresh>0</AutoRefresh> <DataSources> <DataSource Name="DataSource1"> <DataSourceReference>Live Data</DataSourceReference> <rd:SecurityType>None</rd:SecurityType> <rd:DataSourceID>827954ef-81fc-4a34-8f40-5354265d867b</rd:DataSourceID> </DataSource> </DataSources> </Report> 

Ce que j'essaye de faire est d'get toutes les instances de DataSources. Après des heures de combat, j'ai réalisé que je devais utiliser plusieurs namespaces et les referencer avant ma sélection. C'est ma requête maintenant:

 ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition' AS ns, 'http://schemas.microsoft.com/sqlserver/reporting/2010/01/componentdefinition' AS cl, 'http://schemas.microsoft.com/SQLServer/reporting/reportdesigner' AS rd) SELECT c.*, CAST( CONVERT(VARBINARY(MAX), c.Content) AS XML), G.value('ns:DataSource[1]/rd:SecurityType[1]', 'NVARCHAR(MAX)') AS 'SecurityType', G.value('ns:DataSource[1]/ns:DataSourceReference[1]', 'NVARCHAR(MAX)') AS 'DataSourceReference', G.value('ns:DataSource[1]/rd:DataSourceID[1]', 'NVARCHAR(MAX)') AS 'DataSourceID' FROM Catalog c OUTER APPLY (SELECT CAST( CONVERT(VARBINARY(MAX), c.Content) AS XML)) as Content(c) OUTER APPLY Content.c.nodes('//ns:DataSources') AS DS(G) WHERE c.Type NOT IN (5, 4) 

Maintenant, je suis extrêmement énigmatique car cela ne fonctionne qu'avec peu de XML. Je sais qu'il existe un autre moyen d'extraire cette information (je crois en utilisant local-name() ) mais je voudrais non seulement le faire fonctionner (de toute façon possible) mais aussi comprendre pourquoi cela ne fonctionne pas dans sa forme actuelle ( si ce n'est pas juste un manque de connaissance mais une contrainte SQL / XML).

–edit: J'ai utilisé OUTER APPLY pour get tous les NULL qui ne fonctionnent pas, une fois que je sais que la requête est sur place je la changerais en CROSS

Pour la comparaison c'est le début du XML que la requête returnne les bonnes valeurs pour:

 <Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner"> <DataSources> <DataSource Name="DataSource1"> <DataSourceReference>Live Data</DataSourceReference> <rd:SecurityType>None</rd:SecurityType> <rd:DataSourceID>956f67a3-7d7b-46cd-acb2-0e6490d0d33a</rd:DataSourceID> </DataSource> </DataSources> 

Je serais éternellement reconnaissant pour toute aide à comprendre le problème ci-dessus.

PS. Je déteste XML en SQL!

L'URI de l'espace de nommage par défaut dans le XML est:

 xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition" 

alors qu'au début de la requête, vous avez un URI différent mappé au préfixe ns :

 'http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition' AS ns 

c'est peut-être le problème. Si vous avez des namespaces différents dans un document XML différent, vous ne pouvez pas ignorer l'espace de noms en utilisant local-name() , par exemple:

 ;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/reporting/2010/01/componentdefinition' AS cl, 'http://schemas.microsoft.com/SQLServer/reporting/reportdesigner' AS rd) SELECT c.*, CAST( CONVERT(VARBINARY(MAX), c.Content) AS XML), G.value('*[local-name()="DataSource"][1]/rd:SecurityType[1]', 'NVARCHAR(MAX)') AS 'SecurityType', G.value('*[local-name()="DataSource"][1]/*[local-name()="DataSourceReference"][1]', 'NVARCHAR(MAX)') AS 'DataSourceReference', G.value('*[local-name()="DataSource"][1]/rd:DataSourceID[1]', 'NVARCHAR(MAX)') AS 'DataSourceID' FROM Catalog c OUTER APPLY (SELECT CAST( CONVERT(VARBINARY(MAX), c.Content) AS XML)) as Content(c) OUTER APPLY Content.c.nodes('//*[local-name()="DataSources"]') AS DS(G) WHERE c.Type NOT IN (5, 4)