【问题标题】:T-SQL select all XML nodes as rows from RDL dataT-SQL 从 RDL 数据中选择所有 XML 节点作为行
【发布时间】:2011-08-10 03:03:05
【问题描述】:

我正在尝试从包含 XML 列的表中进行选择。我想获取特定节点并为每个节点创建一行。

XML 直接从 Reporting Services 数据库中获取,包含 RDL(报告)结构。我的目标是显示每个报告的所有 ‹Textbox›‹Value›example‹/Value›‹/Textbox› 值。 ‹Textbox› 节点的位置是不可预测的(它可以是 XML 结构中某处任何元素的一部分)。

以下是当前代码,但由于某种原因 id 不起作用:


IF object_id('tempdb..#c') IS NOT NULL
   DROP TABLE #c

select top 50
     path as reportpath
    ,name as reportname
    ,convert(xml, convert(varbinary(max), content)) as reportxml
into
    #c  
from 
    reportserver.dbo.catalog
where 
    content is not null
order by creationdate desc

-----------------------------------------
DECLARE @x XML
SELECT @x = 
( SELECT 
     [reportpath]
    ,[reportname]
    ,[reportxml].query('
            for $a in //../Textbox
            return ‹Textbox
            valueX="{$a/Value}"
            /›
        ')
  FROM #c AS reports 
  FOR XML AUTO
)
select @x
-----------------------------------------
SELECT [reportpath]    = T.Item.value('../@reportpath', 'nvarchar(max)'),
       [reportname]    = T.Item.value('../@reportname', 'nvarchar(max)'),
       value     = T.Item.value('@value' , 'nvarchar(max)')
FROM   @x.nodes('//reports/Textbox') AS T(Item)

下面的示例显示了包含“值”的示例“文本框”:


          ‹RowGrouping›
            ‹Width›2.53968cm‹/Width›
            ‹DynamicRows›
              ‹Grouping Name="matrix1_OperationalWeek2"›
                ‹GroupExpressions›
                  ‹GroupExpression›=Fields!OperationalWeek.Value‹/GroupExpression›
                ‹/GroupExpressions›
              ‹/Grouping›
              ‹ReportItems›
                ‹Textbox Name="textbox35"›
                  ‹rd:DefaultName›textbox35‹/rd:DefaultName›
                  ‹Style›
                    ‹BackgroundColor›White‹/BackgroundColor›
                    ‹PaddingLeft›2pt‹/PaddingLeft›
                    ‹PaddingRight›2pt‹/PaddingRight›
                    ‹PaddingTop›2pt‹/PaddingTop›
                    ‹PaddingBottom›2pt‹/PaddingBottom›
                  ‹/Style›
                  ‹ZIndex›8‹/ZIndex›
                  ‹Value›=Fields!OperationalWeek.Value‹/Value›
                ‹/Textbox›
              ‹/ReportItems›
            ‹/DynamicRows›
          ‹/RowGrouping›

PS 我在 stackoverflow 代码格式方面遇到了一些问题,所以我用 ‹ 和 › 替换了 标记。对于那个很抱歉。

【问题讨论】:

    标签: sql xml tsql reporting-services xpath


    【解决方案1】:

    基于 Bret 的博客 ([http://blogs.netconnex.com/2011/05/extracting-ssrs-report-rdl-xml-from.html][1]) 并添加命名空间会给你带来结果......我希望我可以声称我理解得足以解释,但我主要是通过“绊倒”它来找到我的方式。

    --============================================== ===

    ;WITH XMLNAMESPACES (
    DEFAULT 'http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition',
    'http://schemas.microsoft.com/SQLServer/reporting/reportdesigner' AS rd --ReportDefinition
    )
    select top 50 
         c.Path as reportpath 
        --, c.name as reportname 
        ,t.value('@Name','VARCHAR(100)') as TextboxName
        ,t.value('data(Paragraphs/Paragraph/TextRuns/TextRun/Value)[1]', 'varchar(max)') as value 
    from  
        reportserver.dbo.catalog c
    cross apply 
        (select convert(xml, convert(varbinary(max), content))) as R(reportxml) 
    cross apply 
    --Get all the Query elements (The "*:" ignores any xml namespaces) 
        r.reportxml.nodes('//*:Textbox') n(t)        
    where  
        content is not null 
        and c.Type = 2 -- Reports
    order by creationdate desc 
    

    【讨论】:

      【解决方案2】:

      这个简单的 XQuery

      for $a in //Textbox             
       return 
         <Textbox             
            valueX="{$a/Value}"             
         /> 
      

      应用于提供的 XML 文档时(添加命名空间定义以使其格式正确):

      <RowGrouping xmlns:rd="rd">
        <Width>2.53968cm</Width>
        <DynamicRows>
          <Grouping Name="matrix1_OperationalWeek2">
            <GroupExpressions>
              <GroupExpression>=Fields!OperationalWeek.Value</GroupExpression>
            </GroupExpressions>
          </Grouping>
          <ReportItems>
            <Textbox Name="textbox35">
              <rd:DefaultName>textbox35</rd:DefaultName>
              <Style>
                <BackgroundColor>White</BackgroundColor>
                <PaddingLeft>2pt</PaddingLeft>
                <PaddingRight>2pt</PaddingRight>
                <PaddingTop>2pt</PaddingTop>
                <PaddingBottom>2pt</PaddingBottom>
              </Style>
              <ZIndex>8</ZIndex>
              <Value>=Fields!OperationalWeek.Value</Value>
            </Textbox>
          </ReportItems>
        </DynamicRows>
      </RowGrouping>
      

      产生想要的正确结果:

      <?xml version="1.0" encoding="UTF-8"?>
      <Textbox valueX="=Fields!OperationalWeek.Value"/>
      

      因此,如果您无法获得结果,那么您的问题出在其他问题上,而不是在 XQuery 代码中。

      【讨论】:

      • 谢谢。不幸的是,我仍然无法找到错误。我的代码不返回任何“文本框”信息。也许它与编码有关,我还不确定如何解决这个问题......
      【解决方案3】:

      我无法测试这是否有效,但它应该可以满足您的需求。

      select top 50
           path as reportpath
          ,name as reportname
          ,n.t.value('Value[1]', 'varchar(max)') as value
      from 
          reportserver.dbo.catalog
      cross apply
          (select convert(xml, convert(varbinary(max), content))) as c(reportxml)
      cross apply
          c.reportxml.nodes('//Textbox') n(t)       
      where 
          content is not null
      order by creationdate desc
      

      【讨论】:

      • 不幸的是它返回 0 行。也许是某种转换问题或与 XML 结构有关的问题……我仍在努力寻找解决方案
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-28
      • 1970-01-01
      • 2012-01-18
      • 1970-01-01
      • 2012-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多