T-SQL выбирает все узлы XML как строки из данных RDL - PullRequest
1 голос
/ 21 апреля 2011

Я пытаюсь выбрать из таблицы, содержащей столбец XML. Я хотел бы получить конкретный узел и создать строку для каждого.

XML напрямую получен из базы данных служб Reporting Services и содержит структуру RDL (отчет). Моя цель - отобразить все значения ‹Textbox›‹Value›example‹/Value›‹/Textbox› для каждого отчета. Расположение ‹Textbox› узлов непредсказуемо (оно может быть частью любого элемента где-либо в структуре XML).

Ниже приведен текущий код, но по какой-то причине id не работает:

<code>
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)
</code>

Пример ниже показывает образец «Textbox», связанного с «Value»:


          ‹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 У меня возникли проблемы с форматированием кода в стеке, поэтому я заменил метки <и> на ‹и›. Извини за это.

Ответы [ 3 ]

4 голосов
/ 22 ноября 2011

Основано на блоге Брета ([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 
1 голос
/ 21 апреля 2011

Этот простой 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.

0 голосов
/ 21 апреля 2011

Я не могу проверить, работает ли это, но должно делать то, что вы хотите.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...