2015-12-02 36 views
1

解析SSRS報告XML這是報告的XML的頂部:上Report Server數據庫

<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> 

我想要做的就是讓數據源的所有實例。經過數小時的戰鬥之後,我意識到我必須使用多個命名空間並在我的select語句之前引用它們。這是我現在的查詢:

;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) 

現在我非常困惑,因爲它只適用於很少的XML。我知道還有另外一種方法可以提取這些信息(我相信使用local-name()),但是我希望不僅能使其工作(任何可能的方式),還要理解爲什麼它不能以當前的形式工作(如果它不只是缺乏知識,但SQL/XML剋制)。

--edit:我用OUTER APPLY來獲取所有不工作,一旦我知道該查詢點上我要改變它跨越

爲了比較這的NULL是XML的一開始就知道該查詢返回正確的值爲:

<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> 

我會永遠感激任何幫助理解上述問題。

PS。我討厭SQL中的XML!

+0

定義*不起作用* ..我看不到任何明顯的問題將您的查詢與頂部的XML樣本進行比較 – har07

+0

G.value的結果對於頂級結果爲NULL。在添加名稱空間之前,它們對於所有XML都是NULL,但沒有它們是非常有選擇性的 – Moseleyi

+0

Post示例XML,用於演示問題,即查詢返回NULL爲 – har07

回答

1

默認命名空間URI的XML是:

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

而在查詢開始,你有不同的URI映射到前綴ns

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

這可能是問題。如果你有不同的XML文檔在不同的命名空間,則無法避免忽略的命名空間使用local-name(),例如:

;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) 
+0

因此如果報告是使用不同版本的Report Builder等構建的,那麼其XML的模式將改變?我認爲這不重要,因爲XML定義將來自使用2008的Reporting Services?當然,這只是我的假設,爲此我很樂意接受澄清 – Moseleyi

+1

看起來像這樣,不同的命名空間來自不同版本的SSRS。雖然我沒有經驗過SSRS的人來澄清這件事。 – har07