2013-03-15 43 views
1

我对数据库电子邮件有以下T-Sql。使用xquery转换为html?

-- create proc TableToHtml @table varchar(max) as 
declare @table varchar(max) = '(select 1 a, ''one'' b union all select 2, ''two'') t ' 
declare @sql varchar(max) = ' 
    declare @xml xml = (
     select * from ' + @table + ' 
     for xml path(''tr''), root(''table'') 
    ); 
    select @xml' 
declare @tmp table (x xml) 
insert into @tmp exec(@sql) 
declare @x xml = (select x from @tmp) 
select @x 

,并返回

<table> 
    <tr> 
    <a>1</a> 
    <b>one</b> 
    </tr> 
    <tr> 
    <a>2</a> 
    <b>two</b> 
    </tr> 
</table> 

是否有可能写的XQuery让它返回下面的HTML?

<table> 
    <tr> 
    <th>a</th> 
    <th>b</th> 
    </tr> 
    <tr> 
    <td>1</td> 
    <td>one</td> 
    </tr> 
    <tr> 
    <td>2</td> 
    <td>two</td> 
    </tr> 
</table> 

回答

2

我想出了一个更少的黑客。唯一的问题是,如果值为空,它将创建<td />而不是<td></td>。当电子邮件发送到一些旧的Outlook客户端时,会导致一些布局问题。

declare @table varchar(max) = '(select 1 a, ''one'' b union all select 2, ''two'') t ' 
declare @sql varchar(max) = ' 
    declare @xml xml = (
     select * from ' + @table + ' 
     for xml path(''tr''), root(''table'') 
    ); 
    select @xml' 
declare @tmp table (x xml) 
insert into @tmp exec(@sql) 
declare @x xml = (select x from @tmp) 
select @x.query('<body> 
<table> 
    <tr> 
    {for $c in /table/tr[1]/* return element th { local-name($c) } } 
    </tr> 
    { 
    for $r in /table/* 
    return element tr { for $c in $r/* return element td { data($c) } } 
    } 
</table> 
</body>') 
0

主要黑客警报!

有可能是一个更优雅的方式来做到这一点,但这里是快速黑客:

declare @xml xml = (
    select * from (
     select 'a' + '</th><th>' + 'b' as th, null as td 
     union all 
     select null, '1' + '</td><td>' + 'one'  
     union all 
     select null, '2' + '</td><td>' + 'two'  
    ) t 
    for xml path('tr'), root('table') 
); 
select cast(replace(replace(cast(@xml as varchar(max)), '&lt;/th&gt;&lt;th&gt;', '</th><th>'), '&lt;/td&gt;&lt;td&gt;', '</td><td>') as xml) 

输出:

<table> 
    <tr> 
    <th>a</th> 
    <th>b</th> 
    </tr> 
    <tr> 
    <td>1</td> 
    <td>one</td> 
    </tr> 
    <tr> 
    <td>2</td> 
    <td>two</td> 
    </tr> 
</table> 

哈克列表:

  • 使用空值g等th和td在同一个“列”
  • 明确添加你的头值a和b
  • 串联列值,并明确提出的结束和开始标签中间
  • 将XML转换为varchar
  • 更换消毒用尖括号版本这些标签的版本
  • 转换回XML

这在很大程度上大概可以重构使用变量,或许可以从你的输入/数据收集。

注:

一般来说,你应该让你的演示文稿层为您创建的HTML。你可以在你的数据库中创建一个通用函数来从表格中创建html,但已经有很多优秀的表示类,控件等被设计用来完成这个任务。您的应用程序几乎总是可以比您的数据库缩放更好